现在的位置: 首页 > 综合 > 正文

zoj 2974 Just Pour the Water

2018年04月23日 ⁄ 综合 ⁄ 共 1132字 ⁄ 字号 评论关闭

思路:由于M相当之大,因此可以构造矩阵快速幂来求解
mat[i][j]表示第i个被子给第j个被子的水的百分比,如果k==0,则全给自己,mat[i][i]=1.0;
代码如下:

#include <iostream>
#include <fstream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
#include <cmath>
#define MAX 31
using namespace std;
//矩阵乘法一定不要忘记将矩阵初始赋值为0
int n,k,t,m;
double data[21],avg,res;
struct node{
    double kk[MAX][MAX];
}unit,a;
void init()
{
    for(int i=1;i<=MAX;i++)
        for(int j=1;j<=MAX;j++)
        {
            unit.kk[i][j]=(i==j);
            a.kk[i][j]=0;
        }
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lf",&data[i]);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&k);
        if(k==0)
        {
            a.kk[i][i]=1.0;
            continue;
        }
        avg=1.0/k;
        for(int j=1;j<=k;j++)
        {
            scanf("%d",&t);
            a.kk[i][t]=avg;
        }
    }
    scanf("%d",&m);
}
node mul(node aa,node bb)
{
    node cc;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            cc.kk[i][j]=0;
            for(int p=1;p<=n;p++)
                cc.kk[i][j]=cc.kk[i][j]+(aa.kk[i][p]*bb.kk[p][j]);
        }
    return cc;
}
node pow(node aa,int exp)
{
    node p=aa;
    node q=unit;
    while(exp)
    {
        if(exp&1)
            q=mul(q,p);


        exp/=2;
        p=mul(p,p);


    }
    return q;
}
void cal()
{
    node ans=pow(a,m);
    for(int i=1;i<=n;i++)
    {
        res=0;
        for(int j=1;j<=n;j++)
        {
            res+=(ans.kk[j][i]*data[j]);
        }
        if(i!=1)
            printf(" ");
        printf("%.2lf",res);
    }
    printf("\n");
}


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        init();
        cal();
    }
    return 0;
}

抱歉!评论已关闭.