ZOJ-3497-Evolution

题目传送门
第一行n,p n为物钟种类 p为过了多少年
第二行n个数代表 n种初始数量
输入t 代表t种进化
接下来t种 分别为 a b z代表每一年a的百分之z变为b
问p年之后最后一个物钟的数量
注意 物钟种类从0开始 先++
在这里插入图片描述

#include <cstring>
#include <cstdio>
#define  m(a,b) memset(a,b,sizeof a)
typedef long long ll;
typedef double du;
using namespace std;
const int N=200+5;
struct mat{du a[N][N];};
ll n,p;
du b[N];
mat mat_mul(mat x,mat y)
{
    mat res;
    m(res.a,0);
    for(ll i=1;i<=n;i++)
        for(ll j=1;j<=n;j++)
            for(ll k=1;k<=n;k++)
                res.a[i][j]+=x.a[i][k]*y.a[k][j];
    return res;
}
mat mat_pow(mat c,ll p)
{
    mat res;
    m(res.a,0);
    for(int i=1;i<=n;i++)
        res.a[i][i]=1.0;
    while(p)
    {
        if(p&1)
            res=mat_mul(res,c);
        c=mat_mul(c,c);
        p>>=1;
    }
    return res;
}
int main()
{
    while(~scanf("%lld%lld",&n,&p),n||p)
    {
        for(ll i=1;i<=n;i++)
           scanf("%lf",&b[i]);
        mat c;
        m(c.a,0);
        for(ll i=1;i<=n;i++)
            c.a[i][i]=1.0;             //构造进化关系矩阵
        ll t;
        scanf("%lld",&t);
        while(t--)
        {
            ll x,y;
            du z;
            scanf("%lld%lld%lf",&x,&y,&z);
            x++,y++;
            c.a[x][x]-=z;
            c.a[y][x]+=z;
        }
        mat ans=mat_pow(c,p);
        du fin=0;
        for(int i=1;i<=n;i++)
            fin+=ans.a[n][i]*b[i];    //乘以最初的那个各个物种数量的矩阵
        printf("%.0f\n",fin);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_42576687/article/details/87213270
ZOJ