码迷,mamicode.com
首页 > 其他好文 > 详细

hdu1005-Number Sequence-(循环节)

时间:2019-08-08 18:47:17      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:display   str   size   mem   直接   splay   stack   stream   onclick   

题意:已知f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7,给出A,B,n,求f(n)

题解:n巨大,循环肯定超时,在模7的条件下,0<=f(n)<=6,一共7种选择,则f(n-1)和f(n-2)各有7种选择,共49种组合,至少在第50个组合必定会和前面的重复,找出循环节。

坑:不知网上为什么都说找连续两个1的循环节,有大神指出这是错误的,当a和b是某两个数时,序列是1,4,6循环,但我忘记是哪两个数了,也找不到博客。

在我看来,两重循环找出相同的比较稳妥,而不是找两个1。

技术图片
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;

int a,b,n;
int f[10086];

int main()///hdu1005
{
    while(scanf("%d %d %d",&a,&b,&n)!=EOF&&(a+b+n))
    {
        memset(f,0,sizeof(f));
        f[1]=f[2]=1;
        int i,j;
        int minn=min(n,100);
        for(i=3;i<=minn;i++)
            f[i]=(a*f[i-1]+b*f[i-2])%7;

        ///找第一次和第二次出现的循环节
        int cha=-1;
        for(i=3;i<=minn;i++)
        {
            for(j=i+1;j<=minn;j++)///不吝啬这点时间找出循环节
            if( f[i]==f[j] && f[i+1]==f[j+1] )
            {
                cha=j-i;///循环节的差
                break;
            }
            if(cha!=-1)
                break;
        }
        /// 此时i是循环节的起点
        int idx;
        if(cha==-1)///数据太少,没有找到循环节,直接求
        {
            idx=n;
        }
        else
        {
            n=n+cha;
            idx=(n-2)%cha;
            if(idx==0)
                idx=2+cha;
            else
                idx=2+idx;
        }
        printf("%d\n",f[idx]);
    }
    return 0;
}
hdu1005

 

hdu1005-Number Sequence-(循环节)

标签:display   str   size   mem   直接   splay   stack   stream   onclick   

原文地址:https://www.cnblogs.com/shoulinniao/p/11323003.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!