HDU1005:Number Sequence(循环节)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 180466 Accepted Submission(s): 44856
Problem Description
A number sequence is defined as follows:
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
Given A, B, and n, you are to calculate the value of f(n).
Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
Output
For each test case, print the value of f(n) on a single line.
Sample Input
1 1 3 1 2 10 0 0 0
Sample Output
2 5
思路:
像这种范围这么大的,一般都是有规律的,找出循环节最重要。
先说说这里为什么直接认为49就是周期吧(就是他们所说的循环节)。
因为首先,任意一个数mod7结果为0到6这7个值,两个数就有7*7种组合,f(n)表达式又是一个递推式,f(1)=f(2)=1。
把 1 1 X 记为第一种组合可能,就下来就是 1 X Y ,再接下来是 X Y Z .... 一直到 1 1 X
1 1 X ... ... 1 1 X, 可以看到,若把1 1 X整体看作第一个,那么后面那个 1 1 X就肯定是第 50 个(不排除省略号内 出现过 1 1 X,所以这第50个可能不是首次出现的),由于只可能有49种组合,且该式为递推式,那么前49个组合中必须出现所有的情况。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std ;
#define maxn 50
int f[maxn] ;
int main(){
int a , b , n ;
while(scanf("%d%d%d" , &a , &b , &n)){
if(a==0&&b==0&&n==0)
break ;
memset(f , 0 , sizeof(f)) ;
f[0] = f[1] = 1 ;
int T = 1 ;
int i ;
for(i=2 ; i< maxn ; i++){
f[i] = (a * f[i-1] + b * f[i-2])%7 ;
if(f[i] == 1 && f[i-1] == 1 ){
break ;
}
}
T = i-1 ;
// i-1 就是一个周期里数字个数
n%=T ;
if(n==0) //一个周期里面的最后一个数字
printf("%d\n" , f[T-1]) ;//下标从 0 开始 所以T-1
else printf("%d\n" , f[n-1]) ;
}
return 0 ;
}