POJ 3735 Training little cats(矩阵乘法)

【题目链接】 http://poj.org/problem?id=3735

【题目大意】

  有一排小猫,给出一系列操作,包括给一只猫一颗花生,
  让某只猫吃完所有的花生以及交换两只猫的花生,
  求完成m次操作集合之后每只猫的花生数量

【题解】

  创建一个1*(n+1)的初始矩阵,
  对于给第i只猫一个花生就相当于乘上修改了A[0][i]的单位矩阵
  如给第一只猫一个花生就修改A[0][1]为1
  得到:
    1 1 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 1
  然后我们用初始矩阵去乘这个矩阵,就完成了加的操作
  对于让第i只猫吃完所有的花生,我们将A[i][i]修改为0
  如让第三只猫吃完花生,那么就相当于将A[3][3]改为0
  得到
    1 0 0 0
    0 1 0 0
    0 0 1 0
    0 0 0 0
  然后我们用初始矩阵去乘这个矩阵,就完成了清零的操作
  对于交换花生的操作,我们交换单位矩阵的第x和y行,然后相乘即可
  比如交换第一只猫和第三只猫的花生,我们就得到
    1 0 0 0
    0 0 0 1
    0 0 1 0
    0 1 0 0
  乘到初始矩阵上即可
  我们发现经过这些操作,我们最后会得到一个操作集合的矩阵表达
  而这些操作的变换其实不用整个乘上矩阵,只要直接修改单位矩阵的部分值即可
  第一种操作的影响可以转化为A[0][x]++
  第二种操作的影响可以转化为A[0~n][x]=0
  第三种操作的影响可以转化为i_0^n swap(A[i][x],A[i][y])
  那么我们直接计算转置矩阵即可。

【代码】

#include <cstdio>
#include <vector>
#define rep(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef long long LL; 
typedef vector<vector<LL> > mat;
LL n,m,k,x,y;
char op[10];
mat mul(mat &A,mat &B){
    mat C(A.size(),vector<LL>(B[0].size()));
    rep(i,A.size())rep(k,B.size())if(A[i][k]){
        rep(j,B[0].size())C[i][j]+=A[i][k]*B[k][j];
    }return C;
}
mat pow(mat A,LL n){
    mat B(A.size(),vector<LL>(A.size()));
    rep(i,A.size())B[i][i]=1;
    for(;n;n>>=1){if(n&1)B=mul(B,A);A=mul(A,A);}
    return B;
}
int main(){
    while(scanf("%lld%lld%lld",&n,&m,&k),n+m+k){  
        mat A(n+1,vector<LL>(n+1));
        rep(i,n+1)A[i][i]=1;
        while(k--){
            scanf("%s",&op);
            if(op[0]=='g'){
                scanf("%lld",&x);
                A[0][x]++;
            }else if(op[0]=='e'){
                scanf("%lld",&x);
                rep(i,n+1)A[i][x]=0;
            }else{
                scanf("%lld%lld",&x,&y);
                rep(i,n+1)swap(A[i][x],A[i][y]);
            }
        }if(m){
            A=pow(A,m);
            printf("%lld",A[0][1]);
            for(int i=2;i<=n;i++)printf(" %lld",A[0][i]);
            puts("");
        }else{
            printf("0");
            rep(i,n-1)printf(" 0");
            puts("");
        }
    }return 0;
}
原文地址:https://www.cnblogs.com/forever97/p/poj3735.html