HDU1005 Number Sequence

 1 #include<stdio.h>
 2 void fast_pow(int a[][2], int b[][2]) 
 3 {
 4   int c[2][2];
 5 
 6   c[0][0] = (a[0][0]*b[0][0] + a[0][1] * b[1][0]) % 7;
 7   c[0][1] = (a[0][0]*b[0][1] + a[0][1] * b[1][1]) % 7;
 8   c[1][0] = (a[1][0]*b[0][0] + a[1][1] * b[1][0]) % 7;
 9   c[1][1] = (a[1][0]*b[0][1] + a[1][1] * b[1][1]) % 7;
10 
11   a[0][0]=c[0][0];
12   a[0][1]=c[0][1];
13   a[1][0]=c[1][0];
14   a[1][1]=c[1][1];
15 }
16 int main() 
17 {
18   int A,B,n;
19   int a[2][2],b[2][2];
20   while (scanf("%d%d%d", &A,&B,&n) , n || A || B) {
21       a[0][0]=A;
22       a[0][1]=B;
23       a[1][0]=b[0][0]=b[1][1]=1;
24       a[1][1]=b[0][1]=b[1][0]=0;
25       n--;
26       while (n){
27           if (n & 1)
28               fast_pow(b, a);
29           fast_pow(a, a);
30           n >>= 1;
31       }
32       printf ("%d\n", (b[1][0]+b[1][1])%7);//因为忘了对7求余,贡献好几个WA 
33   }
34   return 0;
35 }

快速幂的典型例题,本题还可以利用求循环阶来求!代码如下:

 1 /*
 2 循环阶最大为49,因为每一个f[i]都有它前面的两个f[i-1]和f[i-2]决定,
 3 而每个f[i-1]和f[i-2]的取值范围都是0~6共七个,所以f[i]的变换范围是7*7=49个,
 4 所以循环阶一定不超过49. 
 5 */ 
 6 #include <stdio.h>
 7 #include <string.h>
 8 #include <math.h>
 9 int f[50];
10 int main()
11 {
12     int a,b,n,i,j;
13     int k[7][7];
14     f[1]=1;f[2]=1;
15     while (scanf("%d%d%d",&a,&b,&n),a||b||n)
16     {
17         memset(k,0,sizeof(k));
18         k[1][1]=2;
19         for (i=3;i<=50;i++)
20         {
21             f[i]=a*f[i-1]+b*f[i-2];
22             f[i]%=7;
23             if (k[f[i]][f[i-1]]) break;
24             k[f[i]][f[i-1]]=i;
25         }
26         j=i-k[f[i]][f[i-1]];//计算机循环阶 
27         n-=k[f[i]][f[i-1]];//先减去循环阶前的乱序部分 
28         n%=j;
29         if (n==0) n+=j;//如果恰好是0,需加1 
30         n+=k[f[i]][f[i-1]];//最后再加上刚才减去的部分 
31         printf("%d\n",f[n]);
32     }
33 }

posted on 2012-12-02 11:02  小花熊  阅读(173)  评论(0编辑  收藏  举报

导航