您的位置:首页 > 其它

zoj 2974 Just Pour the Water (矩阵快速幂,简单)

2014-02-20 20:57 381 查看
题目

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

#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: