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 }

你可能感兴趣的:(sequence)