#include

HDU1005:Number Sequence(循环节)

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).
 

 

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 ;
}

 

posted @ 2017-10-13 13:37  0一叶0知秋0  阅读(111)  评论(0编辑  收藏  举报