HDU 1005 Number Sequence

【题目】                                                  


 

Number Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 75924    Accepted Submission(s): 17659

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
 
Author
CHEN, Shunbao
 
Source
ZJCPC2004
 
Recommend
JGShining

【分析】                                                     
  一看到这个题,就直接用递归做了:
/*============================================================================*\
 * HDU 1005 Number Sequence 直接递归 很明显不可行 
 * 2013/04/04 
 * @CocoonFan 
\*============================================================================*/ 

#include<iostream>

using namespace std;

int a, b,n;
int f(int n)
{
    if(n <3) return 1;
    return (a*f(n - 1) + b*f(n - 2))%7;
}

int main()
{
    while(true)
    {
        cin >> a >> b >> n;
        if(!(a||b||n)) break;
        cout << f(n) << endl;
    }
    return 0;
}

一提交。。。。。。。。很明显直接暴力是行不通的。

于是我就思考能不能用循环的方法来做,嗯。。。。。应该可行:

于是:

/*============================================================================*\
 * HDU 1005 Number Sequence 非递归方法 超时 
 * 2013/04/04 
 * @CocoonFan
\*============================================================================*/ 

#include<iostream>
using namespace std;

int main()
{
    int a, b, n, t1, t2, t3;
    while(true)
    {
        cin >> a >> b >> n;
        if(!(a||b||n)) break;
        t1 = t2 = t3 = 1;
        for(int i = 3; i <= n; ++i)
        {
            t3 = (a*t2 + b*t1)%7;
            t1 = t2;
            t2 = t3;
        }
        cout << t3 << endl;
    }
    return 0;
}

很遗憾最后还是超时了。。。。。。。
于是我就跪了。

后来在网上查资料看了看,原来有个规律:

 因为这是一个递归,结果%7之后余数只有0,1,2,3,4,5,6七种情况,由于后一项是由前两项推出来的所以最终的结果最多只有7*7=49中可能。

有了这个规律一切就好办了:

/*============================================================================*\
 * HDU 1005 Number Sequence 非递归方法 
 * 2013/04/04 
 * @CocoonFan
\*============================================================================*/ 

#include<iostream>
using namespace std;

int main()
{
    int a, b, n, t1, t2, t3;
    while(true)
    {
        cin >> a >> b >> n;
        if(!(a||b||n)) break;
        n %= 49;/////////////////////////只需要加上这句话就够了 
        t1 = t2 = t3 = 1;
        for(int i = 3; i <= n; ++i)
        {
            t3 = (a*t2 + b*t1)%7;
            t1 = t2;
            t2 = t3;
        }
        cout << t3 << endl;
    }
    return 0;
}

O了终于AC了。。。。。。。。。

原文地址:https://www.cnblogs.com/CocoonFan/p/2999785.html