您的位置:首页 > 产品设计 > UI/UE

hdu-1005 Number Sequence

2016-03-18 13:51 525 查看


Number Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 144163    Accepted Submission(s): 35045


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




[b]Input:
[/b]

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.




[b]Output:
[/b]

For
each test case, print the value of f(n) on a single line.




[b]Sample
Input

[/b]

1
1 3


1
2 1
0

0 0 0

[b]Sample Output
[/b]

[b]2[/b]

[b]5
[/b]



问题解决:

题目给了开始两项的值及一个递推式,并要求编写程序计算第n项f(n)的值,看了题目初以为直接循环或者递归就完了,看了输入的要求后发现循环和递归大概要爆内存或者超时,那这样这题就应该是找规律要么就是可以写出通项,那就先找找规律看看。
仔细观察f(n)
= (A*f(n-1)+B*f(n-2)) mod 7,最后有一个mod 7的过程,那任意一项的结果应该就是出现在{0,1,2,3,4,5,6}里了,且递推式中的A、B是给定的,任意一项又只与前两项构成关系,其中f(n-1)有7种情况,f(n-2)也是有7种情况,则A*f(n-1)+B*f(n-2)有7
* 7种情况,当然,现在看这些好像并没有感觉到它有什么用,不急,我们可以先按循环的方法写一次,跑几组答案看看,多试几次,你就会发现好像各组结果都隐隐显示出这个题的结果是有循环节的!现在,我们可以用到上面的关系了,既然A*f(n-1)+B*f(n-2)只有49种情况,那循环节元素数目必定是要小于或等于49的!下面我们就可以开始写代码了:


#include <cstdio>
#include <algorithm>

namespace {
using std::scanf;
using std::printf;
}

int main(int argc, const char *argv[])
{
int rec[51];
rec[0] = 0;
rec[1] = 1;
rec[2] = 1;
int A, B, n;
while (scanf("%d%d%d", &A, &B, &n), A | B | n) {
int begin = 0;
int end = 0;
int i, j;
int flag = 0;
for (i = 3; i <= n && flag == 0; ++i) {
rec[i] = (A * rec[i - 1] + B * rec[i - 2]) % 7;
for (j = 2; j <= i - 1; ++j) {
if (rec[i] == rec[j] && rec[i - 1] == rec[j - 1]) {
begin = j;
end = i;
flag = 1;
break;
}
}
}

if (flag != 0) {
printf("%d\n", rec[begin + (n - end) % (end - begin)]);
}
else {
printf("%d\n", rec
);
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM