ZOJ 2974 矩阵快速幂

题意 给出n个杯子与初始其中有多少水 “同时”进行如下指令 将其中的水同时分入所指定的杯子 进行x次后 输出杯子剩余水量

队友想出应该是一道快速幂 但并不是过去的用初始杯子的水组成的矩阵乘某个矩阵

可以假想 我们同时拿出所有的水 然后按照要求以一个比例分入要求的杯子

那么 设置基数矩阵c[i][k] 那么beizi[i]=初始杯子[k]*c[i][k] i:1~n k:1~n 等式中的c矩阵是经过快速幂乘后的矩阵

然而。。很幸福的wa了。。

后来队友重打 发现了一个错误:当轮到设置某个杯子的指令时 如果a[i].n==0 即我们根本就不拿出这个杯子的水进行分配 它的c[i][i]初始为1

队友的代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
struct JZ {
    double a[25][25];
} init, unit;
int n;
JZ multi(JZ x, JZ y) {
    JZ z;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            z.a[i][j] = 0.0;
            for (int k = 0; k < n; k++) {
                z.a[i][j] += (x.a[i][k] * y.a[k][j]);
            }
        }
    }
    return z;
}
JZ Pow(JZ x, JZ y, int k) {
    while (k) {
        if (k % 2 != 0)
            y = multi(y, x);
        x = multi(x, x);
        k /= 2;
    }
    return y;
}
void init_JZ(int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            init.a[i][j] = 0.0;
            unit.a[i][j] = 0.0;
        }
    }
}
double aa[25];
int main() {
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        init_JZ(n);
        for(int i=0;i<n;i++)
            scanf("%lf",&init.a[0][i]);
        int tmp=0,xh;
        for(int i=0;i<n;i++){
            scanf("%d",&tmp);
            if(tmp==0)
                unit.a[i][i]=1;
            else{
            for(int j=0;j<tmp;j++){
                scanf("%d",&xh);
                unit.a[i][xh-1]+=1.0/tmp;
            }}
        }
       
        int time;
        scanf("%d",&time);
        
        JZ res=Pow(unit,init,time);
        for(int i=0;i<n;i++){
            printf("%.2f",res.a[0][i]);
            printf(i==n-1?"\n":" ");
        }
        
    }
}

  

  

posted @ 2016-04-16 22:43  天翎月  阅读(282)  评论(0编辑  收藏  举报