zoj_2974_快速幂乘

来源:互联网 发布:stl源码剖析怎么样 编辑:程序博客网 时间:2024/04/28 12:35

//首先,想到用矩阵做,为什么会想到用矩阵呢?因为矩阵用于求多项式的递推式!!!为什么会想到递推式呢?因为题目中的当前时间所处的各个contain的

//水量是由前一秒钟所得出来的,因此得出用递推式做题

//题目中的minute很大,自然想到用快速幂乘了,呵呵,一次测试就ac了,快哉!!!

//够造的矩阵要根据每个桶的倒水量,只要懂得快速幂乘的构造矩阵法,就可以的出构造矩阵

#include<iostream>

#include<cstdio>

#include<memory.h>

#include<cmath>

using namespace std;

 

struct mar

{

double a[21][21];

}m;

 

double a[21];

int n;

 

mar mul(mar a,mar b)

{

mar c;

int i,j,k;

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

c.a[i][j]=0;

for(i=1;i<=n;i++)

{

for(j=1;j<=n;j++)

for(k=1;k<=n;k++)

c.a[i][j]+=a.a[i][k]*b.a[k][j];

}

return c;

}

 

mar div(mar a,int x)

{

if(x==1)

return a;

else if(x&1)

return mul(a,div(a,x-1));

else

{

mar b=div(a,x/2);

return mul(b,b);

}

}

 

int main()

{

int t;

scanf("%d",&t);

while(t--)

{

scanf("%d",&n);

int i,j,k,x;

for(i=1;i<=n;i++)

scanf("%lf",&a[i]);

for(i=1;i<=n;i++)

for(j=1;j<=n;j++)

m.a[i][j]=0;

for(i=1;i<=n;i++)

{

scanf("%d",&k);

if(k)

for(j=1;j<=k;j++)

{

scanf("%d",&x);

m.a[x][i]=1.0/(double)k;    //这里特别注意

}

else

m.a[i][i]=1;

}

scanf("%d",&x);

mar result=div(m,x);

for(i=1;i<=n;i++)

{

double ans=0.0;

for(j=1;j<=n;j++)

ans+=a[j]*result.a[i][j];

if(n!=i)

printf("%.2lf ",ans);

else

printf("%.2lf/n",ans);

}

}

return 0;

}

 

 

 

 

 

 

 

原创粉丝点击