Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 225136 Accepted Submission(s): 57138
#include <stdio.h> #include <string.h> int arr[100]; int k[7][7]; int main(void) { int a, b, n; while(scanf("%d %d %d", &a, &b, &n) == 3 && (a || b || n)) { memset(k, 0, sizeof(k)); int i; arr[1] = arr[2] = 1; k[1][1] = 2; for(i = 3; i < 70; i++) { arr[i] = (a * arr[i - 1] + b * arr[i - 2]) % 7; if(!k[arr[i]][arr[i - 1]])//这两个排列没出现过 k[arr[i]][arr[i - 1]] = i;//标记第一次出现的位置 else//出现过 break;//那就找到了循环节,因为后面就一直重复第一次的位置到现在的位置中间的数字 } int m = k[arr[i]][arr[i - 1]];//m没啥意义,就是写k[arr[i]][arr[i - 1]]太麻烦了 int t = i - m;//找到循环位数 if(n <= m)//如果在之前,在循环之前,直接输出 printf("%d\n", arr[n]); else//在后面,则在循环节中某一个值 printf("%d\n", arr[(n - m) % t + m]); } return 0; }
杭电讨论板块网友提供的测试数据(因为题目的测试数据很水,% 49找1 1都能过)
247 602 35363857 376 392 9671521 759 623 18545473 53 399 46626337 316 880 10470347 0 0 0 ------------------------------------------------------------------------------ Output: 4 3 5 2 3 |
原文:https://www.cnblogs.com/jacobfun/p/11421326.html