这道题目n的取值范围很大,1 <= n <= 100,000,000。因此肯定是需要优化才能AC。
首先我考虑到时是有没有通项公式,研究了一下,没发现什么东西,突然看到两个1时就想到会不会在数组中有循环,然后当下次连续出现两个1时即为一次循环。这时我们就只需计算一个循环周期就可以了。另外,让我更坚定有循环的是公式有个取模运算,因而肯定有一个循环。知道这个思路后代码就简单了。
不过让我感到诡异是在寻找数组规律里的那个循环中,循环的限制条件中我没写,结果直接WA了,然后一直不解,于是加了个i<51试了下AC了。
考虑到f[i]的取值只能在0~6之间。因而,f[i],f[i-1]只有7*7=49种可能的组合,刚开始我并不能确定下一个循环一定会出现1,1.但是后来想了一下,如果有循环的话,1,1肯定会继续出现的,如果不出现就不能算是有循环。因而如有循环1,1肯定会再次出现。
#include <stdio.h> int main() { freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); long n; int a,b,i; int f[51]; while(scanf("%d %d %ld",&a,&b,&n)==3) { if(0 ==a && 0 == b && 0 ==n) break; f[1] = 1; f[2] = 1; for(i=3;i<51;i++) { f[i] = (a*f[i-1]+b*f[i-2])%7; if(f[i]==1 && f[i-1]==1) { break; } } int ans = n%(i-2); if(ans == 0) { printf("%d ",f[i-2]); } else { printf("%d ",f[ans]); } } return 0; }