题意 给出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?" ":" "); } } }