九度OJ 1081:递推数列 (递归,二分法)

来源:互联网 发布:战舰世界大和数据穿深 编辑:程序博客网 时间:2024/04/29 16:58

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:6194

解决:864

题目描述:

给定a0,a1,以及an=p*a(n-1) + q*a(n-2)中的p,q。这里n >= 2。 求第k个数对10000的模。

输入:

输入包括5个整数:a0、a1、p、q、k。

输出:

第k个数a(k)对10000的模。

样例输入:
20 1 1 14 5
样例输出:
8359
来源:
2009年清华大学计算机研究生机试真题

思路:

直接一步一步的递推肯定是要超时的。对这种求第n个数的递推题,有logn的解法。

基本思想是a(n)由a(n/2)得到,逐次循环。

an=p*a(n-1) + q*a(n-2)

可以得到an=p2*a(n-2) + q2*a(n-4)

其中 p2 = (p*p+2*q),q2 = -q*q

这种思想是典型二分法,此题重点是学到了一种解题思想。


代码:

#include <stdio.h>#include <string.h>#include <stdlib.h> int main(void){    int p, q, p2, q2, k;    long long a0, a1, a2, a3;     while (scanf("%lld%lld%d%d%d", &a0, &a1, &p, &q, &k) != EOF)    {        if (k == 0)        {            printf("%lld\n", a0);            continue;        }        a0 %= 10000;        a1 %= 10000;        p %= 10000;        q %= 10000;        while (k>1)        {            a2 = p*a1+q*a0;            while (a2<0)                a2 += 1000000000;            a2 %= 10000;            if (k%2 == 1)            {                a3 = p*a2+q*a1;                while (a3<0)                    a3 += 1000000000;                a3 %= 10000;                a0 = a1;                a1 = a3;            }            else                a1 = a2;            p2 = (p*p+2*q)%10000;            q2 = -q*q;            while (q2<0)                q2 += 1000000000;            q2 %= 10000;            p = p2;            q = q2;            k /= 2;        }        printf("%lld\n", a1);    }     return 0;}/**************************************************************    Problem: 1081    User: liangrx06    Language: C    Result: Accepted    Time:10 ms    Memory:912 kb****************************************************************/


别人的代码,用了另一种递归方式,思想是类似的:

#include<stdio.h>#define MOD 10000long long a0,a1,p,q,k;void matrixpow(long long *data,long long k){        long long t1,t2,t3,t4;                long long d1,d2,d3,d4;        d1 = p;        d2 = q;        d3 = 1;        d4 = 0;        if(k == 1 || k == 0)                return;                matrixpow(data,k/2);        t1 = (data[0]*data[0]+data[1]*data[2])%MOD;        t2 = (data[0]*data[1]+data[1]*data[3])%MOD;        t3 = (data[0]*data[2]+data[2]*data[3])%MOD;        t4 = (data[1]*data[2]+data[3]*data[3])%MOD;        data[0] = t1;        data[1] = t2;        data[2] = t3;        data[3] = t4;        if(k&1)        {                t1 = (data[0]*d1+data[1]*d3)%MOD;                t2 = (data[0]*d2+data[1]*d4)%MOD;                t3 = (data[2]*d1+data[3]*d3)%MOD;                t4 = (data[2]*d2+data[3]*d4)%MOD;                data[0] = t1;                data[1] = t2;                data[2] = t3;                data[3] = t4;        }}void main(){                long long data[4];        long long res;        while(scanf("%lld%lld%lld%lld%lld",&a0,&a1,&p,&q,&k)!=EOF)        {                data[0] = p;                data[1] = q;                data[2] = 1;                data[3] = 0;                matrixpow(data,k-2);                if(k == 0)                        res = a0%MOD;                else                {                        if(k == 1)                                res = a1%MOD;                        else                        {                                if(k>2)                                        res = (data[0]*p*a1+a1*q*data[2]+a0*p*data[1]+a0*q*data[3])%MOD;                                else                                        res = (a1*p+a0*q)%MOD;                        }                }                printf("%lld\n",res);        }}



0 0
原创粉丝点击