您的位置:首页 > 其它

杭电1005题

2012-03-13 20:42 211 查看
由于本人刚涉ACM,水平有点菜,再加上一直在准备考研,所以很难抽时间也很有限的去AC,1005题个人感觉有点难,因此最后 还是看了别人的解答,贴在下面了。

#include <iostream>
using namespace std;
int seq[50];
int main()
{
int A,B,n,i;
while(scanf("%d%d%d",&A,&B,&n) && A+B+n)
{
seq[1]=seq[2]=1;
for(i=3;i<50;i++)
{
seq[i]=(A*seq[i-1]+B*seq[i-2])%7;
if(seq[i]==1 && seq[i-1]==1)
break;
}
n%=(i-2);
if(n==0)
cout<<seq[i-2]<<endl;
else
cout<<seq
<<endl;
}
return 0;
}


这是AC代码,方法是找循环节

因为mod7的关系,而且f(1)=f(2)=1,所以f(n)的值是循环分布的,而且一定会回到f(n-1)=f(n)=1,并且还可得出,这个循环不大于49,因为相邻连个f只有7种取值,这样f(n-1)和f(n)共有49种组合。所以,只要找出循环因子即可,寻找方法正是根据f(n-1)=f(n)再次出现的地方来计算

这是网上的说法,但明显有问题。如:把50改成99,WA
如果一定存在不大于49的寻环节,并且回到f(n-1)=f(n)=1,则不会存在上述问题

找循环节的思路存在以下问题:
1.如何证明一定存在循环节
2.如果存在循环节,循环的范围有大
3.循环一定回到f(n-1)=f(n)=1吗?
可能在中间莫些值循环而不回到f(n-1)=f(n)=1

哪位大牛能回答以上问题还请多多指教
----------------------------------------------------------------------------------
先使用一个自定义的词,循环对,即两个相邻的数,以后循环起点都是这一对数

。
我大概的只说说,别让我证明。
1,由于f(n)与f(n-1)和f(n-2)有关,只要出现循环对,就一定会出现循环节。
2,由于是mod 7,共有49种不重复的相邻数对,即50个数,也就是说在这50个数

里,可能不会出现循环对。而在第51个数出现的时候,即有50个相邻数对的时候

,肯定能找到循环对。
3,循环对不一定是f(n-1)=f(n-2)=1.比如当A=513,B=98的时候,循环对是1和2,

循环节是1,2,4.f(1)=1是没有进入循环的。

所以楼主贴出的那个代码是错误的。我猜测它的错误点在于
1,它假设了在49个数里一定出现循环对,for循环里使用了i<50。而49个数

里才有48个相邻数对,可以不出现循环对。
2,它还假定了循环对一定是1,1,循环体里的跳出条件。而很明显,对于当

A=513,B=98的时候,循环对就不是1,1了。这个AC了的程序,当在49个数里找不

到循环对1,1的时候,这时i=50,假设了循环节长度为48个数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: