矩阵——vijos1049送给圣诞夜的礼品

https://vijos.org/p/1049
其实这道题《十个利用矩阵乘法解决的经典题目》里面有;
这题其实思想,只要你学过矩阵,可以直接出来的;
但是我还是卡住了;
因为矩阵不满足交换律;
矩阵乘法不满足交换律,这个和矩阵的长宽没有关系,它就是不满足交换律;
我还以为只要是方形的就可以交换;
但是我们怎么知道谁前谁后呢,这个和矩阵构造有关;
如果我们的矩阵是以行为单位构造出来,显然它要以行为单位得据算,所以要放到前;
反之后;
那么有没有矩阵满足交换律?

  1. 两个相同的矩阵
    比如快速幂里面的乘法

  2. 原始矩阵
    1000
    0100
    0010
    0001

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#define Ll long long
using namespace std;
struct jv{
    int n,m;
    int a[101][101];
    jv(){n=m=0;memset(a,0,sizeof a);}
}a[11],ans,v;
int n,m,k,x,y;
jv cheng(jv a,jv b){
    jv ans; ans.n=a.n; ans.m=b.m;
    for(int i=1;i<=a.n;i++)
        for(int k=1;k<=a.m;k++)if(a.a[i][k])
            for(int j=1;j<=b.m;j++)
                ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j]);
    return ans; 
}
jv ksm(int y){
    jv ans=v,c=v;
    y-=1;
    while(y){
        if(y&1)ans=cheng(ans,c);
        y>>=1;
        c=cheng(c,c);
    }
    return ans;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++){
        a[i].n=a[i].m=n;
        for(int j=1;j<=n;j++){
            scanf("%d",&x);
            a[i].a[j][x]=1;
        }
    }
    v=a[1];
    for(int i=2;i<=m;i++)v=cheng(a[i],v);   
    ans.n=n; ans.m=1;
    for(int i=1;i<=n;i++)ans.a[i][1]=i;
    if(k>=m)ans=cheng(ksm(k/m),ans);
    for(int i=1;i<=k%m;i++)ans=cheng(a[i],ans);
    for(int i=1;i<=n;i++)cout<<ans.a[i][1]<<' ';
}
posted @ 2017-05-02 16:22  largecube233  阅读(139)  评论(0编辑  收藏  举报