ZOJ 2974-Just Pour the Water(矩阵快速幂)

来源:互联网 发布:c语言平均值数组 编辑:程序博客网 时间:2024/05/19 10:53

Description

Shirly is a very clever girl. Now she has two containers (A and B), each with some water. Every minute, she pours half of the water in A into B, and simultaneous pours half of the water in B into A. As the pouring continues, she finds it is very easy to calculate the amount of water in A and B at any time. It is really an easy job :).

But now Shirly wants to know how to calculate the amount of water in each container if there are more than two containers. Then the problem becomes challenging.

Now Shirly has N (2 <= N <= 20) containers (numbered from 1 toN). Every minute, each container is supposed to pour water into anotherK containers (K may vary for different containers). Then the water will be evenly divided intoK portions and accordingly poured into antherK containers. Now the question is: how much water exists in each container at some specified time?

For example, container 1 is specified to pour its water into container 1, 2, 3. Then in every minute, container 1 will pour its 1/3 of its water into container 1, 2, 3 separately (actually, 1/3 is poured back to itself, this is allowed by the rule of the game).

Input

Standard input will contain multiple test cases. The first line of the input is a single integerT (1 <=T <= 10) which is the number of test cases. And it will be followed byT consecutive test cases.

Each test case starts with a line containing an integer N, the number of containers. The second line containsN floating numbers, denoting the initial water in each container. The followingN lines describe the relations that one container(from 1 to N) will pour water into the others. Each line starts with an integerK (0 <=K <= N) followed by K integers. Each integer ([1,N]) represents a container that should pour water into by the current container. The last line is an integerM (1<=M <= 1,000,000,000) denoting the pouring will continue forM minutes.

Output

For each test case, output contains N floating numbers to two decimal places, the amount of water remaining in each container after the pouring in one line separated by one space. There is no space at the end of the line.

Sample Input

12100.00 100.001 22 1 22

Sample Output

75.00 125.00
Note: the capacity of the container is not limited and all the pouring at every minute is processed at the same time.

                                                                                  

理解了好久的题意>.<...有N 杯水,N种操作,操作次数为M;

思路:f1(n)指的是第一杯水第n 次操作得到的水的数量~

            根据样例,f1(1)=0*f1(0)+1/2*f2(0);f2(1)=1*f1(0)+1/2*f2(0);

                               f1(2)=0*f1(1)+1/2*f2(1);f2(2)=1*f1(1)+1/2*f2(1);

           由递推式可以发现可以得到一个矩阵,矩阵中数是方程的系数   0   1/2

                                                                                                                         1/2 1/2

            矩阵快速幂~~

CODE:

#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <string>#include <cstring>#include <queue>#include <stack>#include <vector>#include <set>#include <map>const int inf=0xfffffff;typedef long long ll;using namespace std;typedef vector<double> vec;typedef vector<vec> mat;mat mul(mat &A,mat &B){    mat C(A.size(),vec(B[0].size()));    for(int i=0;i<A.size();i++){        for(int k=0;k<B.size();k++){            for(int j=0;j<B[0].size();j++){                C[i][j]=C[i][j]+A[i][k]*B[k][j];            }        }    }    return C;}mat pow(mat A,ll m){    mat B(A.size(),vec(A.size()));    for(int i=0;i<B.size();i++)        B[i][i]=1.0;    while(m>0){        if(m & 1) B=mul(B,A);        A=mul(A,A);        m>>=1;    }    return B;}int main(){    //freopen("in.in","r",stdin);    int T,N;    scanf("%d",&T);    while(T--){        double n[25];        scanf("%d",&N);        for(int i=0;i<N;i++){            scanf("%lf",&n[i]);        }        mat A(N,vec(N));        int k,a;        for(int i=0;i<N;i++){//第i个容器            scanf("%d",&k);            if(k==0) A[i][i]=1.0;            for(int j=0;j<k;j++){                scanf("%d",&a);                A[a-1][i]+=(1.0/k);            }        }        ll M;        scanf("%lld",&M);        A=pow(A,M);        for(int i=0;i<N;i++){            double p=0;            for(int j=0;j<N;j++){                p+=A[i][j]*n[j];            }            if(i==0) printf("%.2f",p);            else printf(" %.2f",p);        }        printf("\n");    }    return 0;}



                              f2(1)=1*f1(0)+1/2*f2(0);

                               

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 锅底里面烧黑了怎么办 佳能50镜头跑焦怎么办 g7x镜头进灰了怎么办 leica镜头进灰了怎么办 请问喉咙痒咳嗽该怎么办 喉咙痒咳嗽有痰怎么办 痒咳嗽停不下来怎么办 嗓子疼咳嗽有痰怎么办 上火了喉咙干痒怎么办 喉咙里总是有痰怎么办 1岁宝宝喉咙有痰怎么办 嗓子总感觉有痰怎么办 嗓子痒感觉有痰怎么办 1岁宝宝嗓子有痰怎么办 3岁宝宝嗓子有痰怎么办 喉咙总感觉有痰怎么办 感冒了喉咙有痰怎么办 咽喉有异物感是怎么办 老感觉喉咙有痰怎么办 感冒有痰怎么办最有效 感冒快好了有痰怎么办 喉咙里一直有痰怎么办 一到晚上就咳嗽怎么办 1岁宝宝咳嗽痰多怎么办 3岁宝宝咳嗽痰多怎么办 六岁儿童咳嗽有痰怎么办 很多白痰在喉咙怎么办 我喉咙总是有痰怎么办 喉咙老感觉有痰怎么办 喉咙痒老是有痰怎么办 抽烟多了嗓子疼怎么办 抽烟多了老咳嗽怎么办 抽烟抽多了咳嗽怎么办 嗓子咳出异物臭怎么办 鼻子有鼻涕喉咙有痰怎么办 怀孕39周感冒了怎么办 一口痰卡在喉咙怎么办 鼻塞黄鼻涕黄痰怎么办 小孩咳嗽流黄鼻涕怎么办 小孩鼻塞怎么办最简单方法 有黄鼻涕黄痰怎么办