矩阵 ZOJ

矩阵很早以前写过几次,后来就就一直没想写过,很裸地一道矩阵乘法。先初始化每个瓶子执行M次操作分给其他瓶子的比列,用快速幂。最后一次操作。

上个代码记录一下,被水题卡了,引以为戒。

ZOJ Just Pour the Water

View Code
#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;
}
原文地址:https://www.cnblogs.com/zhang1107/p/2798662.html