/* Авторское решение к областной олимпиаде по информатике 16 февраля 2002 г. Запорожье. (с) Ильяшенко Матвей 2002 г. */ #include <stdio.h> #include <string.h> #ifndef lenL // Размер по умолчанию массива, содержащего длинное число #define lenL 45 #endif /* * Функции дублирования содержимого массива длинного числа * (содержимое копируется из src в dest) * *dest,*src - указатели на массивы длинных чисел */ void cpyL(short *dest,short *src) { int i; for(i=0;i<lenL;i++) dest[i]=src[i]; } inline void dupL(short *dest,short *src) { cpyL(dest,src); } /* * Функция обнуления части элементов массива длинного числа * *a - указатель на массив длинного числа * from=0 - первый элемент, подлежащий обнулению * to=lenL-1 - последний элемент +1, подлежащий обнулению */ void nullL(short *a,int from=0,int to=lenL) { int i; for(i=from;i<to;i++) a[i]=0; } /* * Функция определения первого значащего разряда длинного числа * *a - указатель на массив длинного числа * Возврат: * Номер первого значащего разряда * Если число равно 0, то возвращается 0 */ int firstL(short *a) { int i; for(i=lenL-1;i>=0;i--) if(a[i]!=0) return(i); return(0); } /* * Функция сравнения двух длинных чисел * *a,*b - указатели на массивы длинных чисел * Возврат: * 1 - если a>b * 0 - если a=b * -1 - если a int cmpL(short *a,short *b) { int i; for(i=lenL-1;i>=0;i--) { if(a[i]>b[i]) return(1); if(a[i]<b[i]) return(-1); } return(0); } /* * Функция вывода длинного числа на stdout * *a - указатель на массив длинного числа */ void writeL(short *a) { int i,first; first=firstL(a); printf("%d",a[first]); for(i=first-1;i>=0;i--) printf("%04d",a[i]); } /* * Функция здвига числа влево * *a - указатель на массив длинного числа * n - количество разрядов, на которое сдвигается число */ void shlL(short *a,int n) { int i; for(i=lenL-1;i>=n;i--) a[i]=a[i-n]; nullL(a,0,n); } /* * Функция добавления к длинному числу числа типа short * *a - указатель на массив длинного числа * n - добавляемое число (оно же является переполнением) * Возврат: * 0 - не было переполнения * 1 - было переполнение */ int addL(short *a,short n) { int i=0; long sum; do { sum=(long)(a[i])+(long)(n); a[i]=(short)(sum%10000L); n=(short)(sum/10000L); i++; }while((i!=lenL)&&(n!=0)); return((int)(n)); } /* * Функция добавления к длинному числу a длинного числа b * *a,*b - указатели на массивы длинных чисел * Возврат: * 0 - не было переполнения * 1 - было переполнение */ int addL(short *a,short *b) { int i=0; short n=0; long sum; do { sum=(long)(a[i])+(long)(b[i])+(long)(n); a[i]=(short)(sum%10000L); n=(short)(sum/10000L); i++; }while(i!=lenL); return((int)(n)); } /* * Функция умножения длинного числа на число типа short * *a - указатель на массив длинного числа * n - добавляемое число (оно же является переполнением) * Возврат: * 0 - не было переполнения * 1 - было переполнение */ int mulL(short *a,short n) { int i; short p=0; long mul; for(i=0;i<lenL;i++) { mul=(long)(a[i])*(long)(n)+(long)(p); a[i]=(short)(mul%10000L); p=(short)(mul/10000L); } return((int)(p)); } /* * Функция умножения длинного числа a на длинное число b * *a,*b - указатели на массивы длинных чисел * Возврат: * 0 - не было переполнения * 1 - было переполнение */ int mulL(short *a,short *b) { int i,first_b,res=0; short t[lenL],r[lenL]; nullL(r); first_b=firstL(b); for(i=0;i<=first_b;i++) if(b[i]!=0) { cpyL(t,a); shlL(t,i); mulL(t,b[i]); if(addL(r,t)) res=1; } cpyL(a,r); return(res); } /* * Функция возведения числа x в степень y * *a - указатель на длинное число, в которое будет записан результат * x - основание степени * y - показатель степени * Возврат: * 0 - не было переполнения * 1 - было переполнение */ int powL(short *a,int x,int y) { int i,res=0; nullL(a); addL(a,1); for(i=0;i<y;i++) res+=mulL(a,x); return((int)(res>0)); } short Table[2][180][lenL]; short Result[90][lenL]; void main() { short Sum[lenL],t[lenL],pow[lenL]; long N,K,i,j,k,Pmax; scanf("%ld%ld",&N,&K); Pmax=N/2; for(j=0;j<=N;j++) { nullL(Table[0][j]); addL(Table[0][j],1); } nullL(Result[0]); addL(Result[0],1); for(i=1;i<=Pmax;i++) { for(j=i*2;j<=N;j++) { nullL(Table[i%2][j]); for(k=(i-1)*2;k<=j-2;k++) addL(Table[i%2][j],Table[(i-1)%2][k]); } dupL(Result[i],Table[i%2][N]); } nullL(Sum); powL(pow,K-1,N-Pmax-1); for(i=0;i<=Pmax;i++) { mulL(pow,K-1); dupL(t,pow); mulL(t,Result[Pmax-i]); addL(Sum,t); } writeL(Sum); printf("\n"); }
Комментарии
|
Реклама:
Разработано в студии "Webous" — о проекте — сайта карта —Реклама: