题目分析:由于n的范围在1~100,000,000,所以利用常规的每次保存上次运算结果的方法绝对会超时。题中mod7,即为解题的突破口,
由于mod 7 所以f(n)的值只可能有7种结果(0~6),另由f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.,其中
A * f(n - 1) + B * f(n - 2)的结果所构成的序列的周期最多不过49,因为由排列组合的原理,
f(n-1) 有7中结果,f(n-2)有 7种结果,可得共49种变化。
到此解题就顺理成章了,把每个结果保存在数组中,直到发现数组的值又变回f(n)=1,f(n-1)=1;时,即为数组序列的周期。得到周期i后,最后的f(n)即等于f[n%i]。
实现代码:
1
#include <vector>2
#include "stdio.h"3
#include "iostream.h"4

5

6
int main()7


{8
long n;9
int A,B,f[200];10
while(scanf("%d %d %ld",&A,&B,&n)!=EOF&&A&&B&&n)11

{12
for(int j=0;j<200;j++)13

{14
f[j]=0;15
}16
if(n==1||n==2) 17
cout<<1<<endl;18
else19

{20
long i;21
f[1]=1;22
f[2]=1;23
for(i=3;i<200;i++)24

{25
f[i]=(A*f[i-1]+B*f[i-2])%7;26
if(f[i]==1&&f[i-1]==1)27
break;28
}29
i=i-2;30
f[0]=f[i];31
cout<<f[n%i]<<endl;32
}33
}34
return 0; 35
}36

讨论:在本题AC之后,忽在网上发现了这种解法其实是错误的,因为这个循环的结果序列不一定从第一个开始,所以随着测试数据的增强,定会碰到错误情况,但可能由于HDOJ的测试数据不够强,让我侥幸过关~~~。解决方案是,为所得到的结果序列增加一个标示,当重复出现两次得到同样的序列后,即可确定所得的序列周期即为正确的。
本文深入解析HDOJ中一道难题的高效求解策略,通过分析f(n)=(A*f(n-1)+B*f(n-2))mod7的周期特性,避免超时问题。阐述了如何利用模运算和数组存储技巧,找到序列周期,快速计算大规模数据下的f(n)值。
6086

被折叠的 条评论
为什么被折叠?



