标题:hdu1005说运行时错误 为什么啊 求原因
只看楼主
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:507
帖 子:8890
专家分:53117
注 册:2011-1-18
得分:0 
f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
可以看出几个数学性质
1. A 替换为 A%7 对结果无影响,也就是不管A取何值,只有7种可能
2. B 亦复如是
3. f(n)为周期性函数,因为f(n-1)最多只有7种可能,f(n-2)最多只有7种可能,因此f(n)的周期小于等于49
因此,最快的算法就是建立一个 [7][7][49] 的三维映射表,直接查表就行了,这应该是理论上最快的算法

太数学化不好,退而求其次,只考虑周期不超过49这一点,就可以在49步内直接预测到最终结果
程序代码:
#include <stdio.h>

unsigned foo( unsigned A, unsigned B, unsigned n )
{
    unsigned buf[53] = { 0, 1, 1, (A+B)%7, (A*(A+B)+B)%7 };
    if( n <= 4 )
        return buf[n];
    if( A%7==0 && B%7==0 )
        return 0;

    for( unsigned i=5; i!=n+1; ++i )
    {
        buf[i] = (A*buf[i-1] + B*buf[i-2]) % 7;

        if( buf[i]==buf[4] && buf[i-1]==buf[3] )
            return buf[(n-2)%(i-4)+2];
    }

    return buf[n];
}

int main( void )
{
    for( unsigned A, B, n; scanf("%u%u%u",&A,&B,&n)==3 && !(A==0 && B==0 && n==0); )
        printf( "%u\n", foo(A,B,n) );

    return 0;
}

2015-03-04 11:17
longwu9t
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:6
帖 子:732
专家分:2468
注 册:2014-10-9
得分:0 
回复 10楼 wmf2014
http://acm.hdu.

Only the Code Tells the Truth             K.I.S.S
2015-03-04 12:23
末日泡沫
Rank: 1
等 级:新手上路
帖 子:18
专家分:0
注 册:2015-3-1
得分:0 
回复 10楼 wmf2014
设定大数组 比如long long a[]这样的 是不是不符合规定的?
2015-03-04 14:03
longwu9t
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:小飞侠
威 望:6
帖 子:732
专家分:2468
注 册:2014-10-9
得分:0 
这么多代码 也就是11楼的不超时

10楼的还存在n取值范围的问题

Only the Code Tells the Truth             K.I.S.S
2015-03-04 14:22
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
得分:0 
我在10楼代码数组初始化为1的位置错,放到正确位置后超时,受11楼启发,这的确是建立一个周期表的问题,但不是固定以49为周期,周期不固定,但周期是从元素值1,1开始的,所以如下代码通过,速度0ms。

#include<stdio.h>
void main()
{
    int i,j,a,b,n,f[200];
    while(1)
    {
        scanf("%d%d%d",&a,&b,&n);
        if(a>=1&&b<=1000&&n>=1&&n<=100000000)
        {
            f[0]=1;f[1]=1;
            for(i=2;i<200;i++)
            {//建立周期表
                f[i]=(a*f[i-1]+b*f[i-2])%7;
                if(f[i]==1&&f[i-1]==1)break;
            }
            j=n%(i-1);
            if(j==0)j=i-1;
            printf("%d\n",f[j-1]);
        }
        if(!(a||b||n))break;
    }
}

能编个毛线衣吗?
2015-03-04 15:38
wmf2014
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:216
帖 子:2039
专家分:11273
注 册:2014-12-6
得分:0 
函数递归也轻松实现
正如11楼分析,当a、b值确定后,在不大于49的数据集里必然出现循环(经反复查看循环规律,a=2至6,b=7,14,21时不是在元素值为1,1时循环),所以n%49经过运算就会指向自己循环规律中需要的值,因此可免除数组存储循环数据,下面代码提交通过,时间31ms.
#include<stdio.h>
int seq(int a,int b,int n)
{//函数递归实现
    if(n<3)
        return 1;
    else
        return ((a*seq(a,b,n-1)+b*seq(a,b,n-2))%7);
}
void main()
{
    int a,b,n;
    while(1)
    {
        scanf("%d%d%d",&a,&b,&n);
        if(a>=1&&b<=1000&&n>=1&&n<=100000000)printf("%d\n",seq(a,b,n%49));
        if(!(a|b|n))break;
    }
}

能编个毛线衣吗?
2015-03-05 06:33



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-442346-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.709169 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved