zoukankan      html  css  js  c++  java
  • zoj 2974 Just Pour the Water (矩阵快速幂,简单)

    题目

    对于案例的解释请见下图:

    这道要变动提取一下矩阵,之后就简单了

    具体解释可看代码:

        
    #include <string.h>
    #include <stdio.h>
    #include<algorithm>
    using namespace std;
    
    int num;
    struct matrix
    {
           double a[30][30];//把每次倒水的比率提取出来放在这里面,例如i倒给j几分之几,以便进行计算
    }origin,answ;//answ保存提取出来比率计算后的答案
    
    
    matrix multiply(matrix x,matrix y)//x与y的矩阵乘法
    {
           matrix temp;
           for(int i=1;i<=num;i++)
           {
                   for(int j=1;j<=num;j++)
                   {
                           double ans=0;
                           for(int k=1;k<=num;k++)
                           {
                                   ans+=x.a[i][k]*y.a[k][j];
                           }
                           temp.a[i][j]=ans;
                   }
           }
           
           return temp;
    }
    
    matrix calc(int n)//矩阵快速幂——把提取出来的比率进行n次重复的‘倒’,即n次幂
    {
         while(n)//以下运用二分
         {
                 if(n%2==1)
                        answ=multiply(origin,answ);
                 origin=multiply(origin,origin);
                 n/=2;
         }
         return answ;
    }
    
    int main()
    {
        int t,n,k,m;
        double a[30];
        scanf("%d",&t);
        for(int id=0;id<t;id++)
        {
            memset(answ.a,0,sizeof(answ.a));
            memset(origin.a,0,sizeof(origin.a));
           
            scanf("%d",&n);
            for(int i=1;i<=n;i++)  
                scanf("%lf",&a[i]);
            
            num=n;
            for(int i=1;i<=n;i++)
                answ.a[i][i]=1;
    
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&k);//i要平均的倒给之后的k个人
                if(k==0)
                    origin.a[i][i]=1.0;//不向任何地方倒,相当于都倒给自己,即1/1
                for(int j=1;j<=k;j++)
                {
                    int p;
                    scanf("%d",&p);
                    origin.a[p][i]=1.0/k;//i倒给p的比率
                }
            }
    
            scanf("%d",&m);
            calc(m);//对数据进行处理
    
            for(int i=1;i<=n;i++)//逐个输出答案
            {
                double ans=0;//初始化
                for(int j=1;j<=n;j++)//一列一列处理
                    ans+=answ.a[i][j]*a[j];//处理后的比率*原始数据
                if(i==1)
                    printf("%.2lf",ans);
                else
                    printf(" %.2lf",ans);
            }
            puts("");
        }
        return 0;
    }
    View Code
    一道又一道,好高兴!
  • 相关阅读:
    Kali下的内网劫持(三)
    Kali下的内网劫持(四)
    Kali下的内网劫持(二)
    Kali下的内网劫持(一)
    PHP中is_numeric函数十六进制绕过0day
    Linux之RHEL7root密码破解(三)
    Linux之RHEL7root密码破解(二)
    python selenium3 自动化测试
    spring boot
    记Too many open files错误
  • 原文地址:https://www.cnblogs.com/laiba2004/p/3558377.html
Copyright © 2011-2022 走看看