杭电1005

这道题是继大数求和大数求幂来遇到的较难的题。其实怎么说,也不算难。只是自己没有想到而已。。

先贴一下我AC的代码咯!

#include
int main(void)
{
    int mo[50]={0,1,1};//至少50的循环数组
    int a,b,t;//a和b
    long int n;//第n项
    while(scanf("%d %d %d",&a,&b,&n)!=EOF)
    {
        if((a<=0||b<=0)||n<=0)
            break;//排除a,b,c小于0
        for(t=3;t<50;t++)
        {
            mo[t]=(a*mo[t-1]+b*mo[t-2])%7;
            if(mo[t]==1&&mo[t-1]==1)
            {
                mo[0]=mo[t-2];
                break;
            }
        }
        if(a%7==0&&b%7==0&&n>2)
            printf("%d\n",0);
        else if(a%7==0&&b%7&&n<=2)
            printf("%d\n",1);
        else
            printf("%d\n",mo[n%(t-2)]);
    }
    return 0;
}

代码的话,其实我一开始我是写出来了的,只是都超时了。。这也是没办法的,一开始没考虑到这个遍历会出现这个问题,之后没有优化算法导致一直未能AC。于是百度,这是解决问题的一个好办法!

但是这次百度没给我带来希望,我只是单纯的知道了在49之内会循环,但是在百度上搜到的代码很多都说mo[1]=mo[49],还涉及到了费波纳茨数列,于是我不断的搜索,不断思考,查到了抽屉原理,于是便能49之内会循环的原因。原因是这样的:因为输出的数字在0到6之间,这是无疑的。所有一个数和他前一个数总共有7*7=49种情况,如果刻意要在49个之内不重复,可以,但是,会发现在49次时,所有的情况已经遍历,所有必然有重复!

其次是那个mo[1]=mo[49],虽然我不知道这是哪里来的结论,但是当我拷贝网上的代码测试时,发现那个输出是错误的!于是我更蒙了,便询问了一个高手这道题的解决方法。高手直接点出查找重复的节点。以此循环就可以。于是豁然开朗。只需用mo[2]和mo[1]和一个mo[i]和mo[i-1]比较,当他们相等时,节点便出现了!

于是后边就简单了。。果然,自己思维敏度不够,要更加努力才行了!

你可能感兴趣的:(杭电1005)