zoukankan      html  css  js  c++  java
  • poj 3735 Training little cats(矩阵快速幂,模版更权威,这题数据很坑)

    题目

    矩阵快速幂,这里的模版就是计算A^n的,A为矩阵。

    之前的矩阵快速幂貌似还是个更通用一些。

     下面的题目解释来自 我只想做一个努力的人

    @@@请注意 ,单位矩阵最初构造 行和列都要是(猫咪数+1)!!!然后按照分析的来,分析中矩阵的下标都是从0开始的。

    无法理解的可自行构造案例的矩阵进行验证。

    注意一些细节,有些数据要用64位,不然会wa。

    //可能是因为原本的模版不适用
    
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    
    int num;
    struct matrix
    {
        long long a[105][105];
    }origin,answ;
    
    
    
    matrix multiply(matrix x,matrix y)//矩阵乘法
    {
        matrix temp;
        memset(temp.a,0,sizeof(temp.a));//因为后面的代码变了,所以这里也要初始化了
        for(int i=0;i<=num;i++)
        {
            for(int k=0;k<=num;k++)
            {
                if(x.a[i][k])//据说多加这么一句筛选一下就不超时了?
                {
                    for(int j=0;j<=num;j++)
                    {
                        temp.a[i][j]+=((x.a[i][k]*y.a[k][j]));
                    }
                }
            }
        }
        return temp;
    }
    
    
    matrix calc(matrix a,int n)//矩阵快速幂——a^n
    {
        if(n==1)return a;
        matrix e;
        for(int i=0;i<=num;i++)
            for(int j=0;j<=num;j++)
                e.a[i][j]=(i==j);
    
        while(n)
        {
            if(n&1)
                e=multiply(e,a);
            n>>=1;
            a=multiply(a,a);
        }
        return e;
    }
    
    int main()
    {
    
        // freopen("in.txt", "r+", stdin);   
        // freopen("out.txt", "w+", stdout);  
        int n,k,m;
        char s[5];
        while(scanf("%d%d%d",&n,&m,&k)!=EOF)
        {
            if(n==0&&m==0&&k==0)break;
            num=n;
            for(int i=0;i<=n;i++)
                for(int j=0;j<=n;j++)
                    origin.a[i][j]=(i==j);
    
                while(k--)
                {
                    long long ii,jj;//这种数据也要64位
                    scanf("%s",s);
                    if(s[0]=='g')
                    {
                        scanf("%lld",&ii);
                        origin.a[0][ii]++;
                    }
                    else if(s[0]=='s')
                    {
                        scanf("%lld%lld",&ii,&jj);
                        long long kk;
                        for(int iii=0;iii<=n;iii++)
                        {
                            kk=origin.a[iii][ii];
                            origin.a[iii][ii]=origin.a[iii][jj];
                            origin.a[iii][jj]=kk;
                        }
                    }
                    else
                    {
                        scanf("%lld",&ii);
                        for(int iii=0;iii<=n;iii++)
                        {
                            origin.a[iii][ii]=0;
                        }
                    }
                }
                if(m==0)//之前没考虑到这个?
                    memset(answ.a,0,sizeof(answ.a));
                else
                    answ=calc(origin,m);
                int yi=0;
                for(int i=1;i<=n;i++)
                {
                    if(yi)
                        printf(" ");
                    printf("%lld",answ.a[0][i]);
                    yi=1;
                }
                puts("");
        }
        return 0;
    }
    View Code
    一道又一道,好高兴!
  • 相关阅读:
    万恶的VS2010 快捷键
    C# 入门篇之listview用法
    MySQL安装常见错误及解决方案
    【转】MySQL命令
    #字符串 770. 单词替换
    #字符串 字符串替换 POJ
    # 4 Values whose Sum is 0 (POJ
    #Shopping HDU
    #疯狂搜索( POJ-1200) #哈希
    #哈希 题目:Eqs(POJ
  • 原文地址:https://www.cnblogs.com/laiba2004/p/3561502.html
Copyright © 2011-2022 走看看