HDU1005

矩阵快速幂?递归取模?

//超时解法:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<string>
#include<cmath>
#include<ctype.h>
#include<climits>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<functional>
#define stop while(1);
#define lowbit(x) (x&(-x))
#define eps (1e-8)
#define pi (acos(-1.0))
#define maxint INT_MAX
#define maxlong 0xFFFFFFFFFFFFFFFLL 
using namespace std;
typedef unsigned long long u64;

int a, b;
int solve(int n) {
    if (n == 1 || n == 2)
        return 1;
    else 
        return (a * solve(n - 1) + b * solve(n - 2)) % 7;
}

int main () {
    int m, p, n;
    while (cin >> m >> n >> p) {
        if (!m && !n && !p)
            return 0;
        a = m;
        b = n;
        int ans = solve(p) % 7;
        cout << ans << endl;    
    } 
}

 没事少用递归一般都会超时

//矩阵快速幂:

//想不到(不会。。。

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;

const int bc=2;
const int mod = 7;
struct matrix
{
    int x[bc][bc];
};



matrix mutimatrix(matrix a,matrix b)
{
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    for(int i=0;i<bc;i++)    //答案的行
    {
        for(int j=0;j<bc;j++)   //答案的列
        {
            for(int k=0;k<bc;k++)
            {
                temp.x[i][j]+=a.x[i][k]*b.x[k][j];
                temp.x[i][j]%=mod;
            }
        }
    }
    return temp;
}

matrix powmatrix(matrix a,int b)
{
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    //初始化矩阵为单位阵
    for(int i=0;i<bc;i++)
        temp.x[i][i]=1;
    while(b)
    {
        if(b%2==1)
            temp=mutimatrix(temp,a);
        a=mutimatrix(a,a);
        b=b/2;
    }
    return temp;
}

int main()
{
    int a,b,n;
    //freopen("in.txt","r",stdin);
    while(scanf("%d %d %d",&a,&b,&n)!=EOF)
    {
        if(a==0&&b==0&&n==0) break;
        matrix st;
        //因为每次都是a个F(n-1)和b个F(n-2)相加,所以这里如此初始化
        //Fib数列这里就直接单位阵
        st.x[0][0]=a;
        st.x[0][1]=1;
        st.x[1][0]=b;
        st.x[1][1]=0;
        st=powmatrix(st,n-1);
        printf("%d
",(st.x[0][1]+st.x[1][1])%mod);
    }
    return 0;
}

神仙解法(时间和空间的高度优化)

// 取模的题一般都有规律
// 二阶的话周期为49
#include <iostream>  
using namespace std;  
int arr[50];  
int main()  
{  
    int n, a, b;  
    arr[1] = arr[2] = 1;  
    while (cin >> a >> b >> n) {  
        if (a == 0 && b == 0 && n == 0)  
            break;  
        int minn = n < 50 ? n : 50;//一个小小的优化  
        for (int i = 3; i <= minn; i++) {  
            arr[i] = (a * arr[i - 1] + b * arr[i - 2]) % 7;  
        }  
        cout << arr[n % 49] << endl;  
    }  
    return 0;  
}  
作者:LightAc
出处:https://www.cnblogs.com/lightac/
联系:
Email: dzz@stu.ouc.edu.cn
QQ: 1171613053
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/lightac/p/10619171.html