矩阵 ZOJ
矩阵很早以前写过几次,后来就就一直没想写过,很裸地一道矩阵乘法。先初始化每个瓶子执行M次操作分给其他瓶子的比列,用快速幂。最后一次操作。
上个代码记录一下,被水题卡了,引以为戒。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int MM = 30; #define fuck puts("fuck"); int N,M; double num[MM]; struct Mat { int h,w; double c[MM][MM]; void reset() { for(int i=0;i<MM;i++) for(int j=0;j<MM;j++) c[i][j]=0.0; } Mat friend operator*(Mat x,Mat y) { int i,j,k; Mat z; z.reset(); z.h=x.h,z.w=y.w; for(i=1;i<=x.h;i++) { for(j=1;j<=y.w;j++) { for(k=1;k<=x.w;k++){ z.c[i][j]+=x.c[i][k]*y.c[k][j]; } } } return z; } }; Mat a; void get_data() { int i,j,k,x; double tmp; scanf("%d",&N); for(i=1;i<=N;i++) scanf("%lf",&num[i]); a.reset(); a.h=a.w=N; for(i=1;i<=N;i++) { scanf("%d",&k); if(k==0) a.c[i][i]=1.0; else { tmp=1.0/(1.0*k); while(k--) { scanf("%d",&x); a.c[i][x]=tmp; } } } scanf("%d",&M); } void show(Mat x) { int i,j,k; for(i=1;i<=x.h;i++) { for(j=1;j<=x.w;j++) { printf("%.2lf ",x.c[i][j]); } printf("\n"); } } Mat mul_n(Mat x,int m) { int i,j,k; Mat ans; ans.h=x.h, ans.w=x.w; ans.reset(); for(i=0;i<=x.h;i++) ans.c[i][i]=1.0; while(m) { if(m&1) ans=ans*x; m>>=1; x=x*x; } return ans; } void solve() { int i,j,k; Mat ans=mul_n(a,M),tmp; tmp.h=1,tmp.w=N; for(i=1;i<=N;i++) tmp.c[1][i]=num[i]; ans=tmp*ans; printf("%.2lf",ans.c[1][1]); for(i=2;i<=N;i++) printf(" %.2lf",ans.c[1][i]); puts(""); } int main() { int ca; scanf("%d",&ca); while(ca--) get_data(),solve(); return 0; }