VOJ 1049 送给圣诞夜的礼物 (矩阵 )

来源:互联网 发布:贪心算法解决背包问题 编辑:程序博客网 时间:2024/04/30 09:23

题目大意:

对于初始序列,1,2,3,4,5 --- n 来说。给出m次变换,让你按照这样的方式的顺序执行k次。问最后得到的序列

题目链接:https://vijos.org/p/1049

思路分析:

0 0 1 0     1     3

1 0 0 0     2     1

0 1 0 0  * 3 =  2

0 0 0 4     4     4


所以就按照这样把左边的矩阵构造出来,然后快速幂。

模拟最后几次。


#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#define N 30using namespace std;const int mod = 10007;struct matrix{    int a[111][111];}origin;int op[111][111];int n,m,k;matrix multiply(matrix x,matrix y){    matrix temp;    memset(temp.a,0,sizeof(temp.a));    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        {            for(int k=0;k<n;k++)            {                temp.a[i][j]+=x.a[i][k]*y.a[k][j];             //   temp.a[i][j]=(temp.a[i][j])%mod;            }        }    }    return temp;}matrix matmod(matrix a,int k){    matrix res;    memset(res.a,0,sizeof res.a);    for(int i=0;i<n;i++)res.a[i][i]=1;    while(k)    {        if(k&1)        res=multiply(res,a);        k>>=1;        a=multiply(a,a);    }    return res;}void print(matrix x){    for(int i=0;i<n;i++)    {        for(int j=0;j<n;j++)        printf("%d ",x.a[i][j]);        puts("");    }    printf("---------------\n");}int main(){    while(scanf("%d%d%d",&n,&m,&k)!=EOF)    {        matrix move,fmove;        memset(fmove.a,0,sizeof fmove.a);        for(int i=0;i<n;i++)        fmove.a[i][i]=1;        for(int i=0;i<m;i++)        {            for(int j=0;j<n;j++)            {                scanf("%d",&op[i][j]);                //move.a[j][op[i][j]]=1;            }            memset(move.a,0,sizeof move.a);            for(int j=0;j<n;j++)            {                move.a[j][op[i][j]-1]=1;            }            fmove=multiply(move,fmove);        }        //print(fmove);        int time=k/m;        fmove = matmod(fmove,time);        memset(origin.a,0,sizeof origin.a);        for(int i=0;i<n;i++)        origin.a[i][0]=(i+1);        matrix ans = multiply(fmove,origin);        for(int i=0;i<(k%m);i++)        {            memset(move.a,0,sizeof move.a);            for(int j=0;j<n;j++)            move.a[j][op[i][j]-1]=1;            ans=multiply(move,ans);        }        for(int i=0;i<n;i++)        {            printf("%d%c",ans.a[i][0],i==n-1?'\n':' ');        }    }    return 0;}


0 0
原创粉丝点击