当前位置: 代码迷 >> 综合 >> POJ 3735 构造矩阵乘法
  详细解决方案

POJ 3735 构造矩阵乘法

热度:46   发布时间:2024-01-20 20:32:25.0

看来还是要吧这个矩阵乘法理解透啊!

我的题解大体和网上的一样吧。没有什么可取性。

对于矩阵,我们熟悉的操作有两种,交换与置零。

我们有初始的矩阵T[ A,B,C,D ];

交换矩阵为

                       | 1 0 0 0 |       

[ A,B,C,D ]  X  | 0 0 1 0 |  =>[ A C B D ]

                       | 0 1 0 0 |       

                       | 0 0 0 1 |

置零矩阵为

                       | 1 0 0 0 |       

[ A,B,C,D ]  X  | 0 1 0 0 |  =>[ A B 0 D ]

                       | 0 0 0 0 |       

                       | 0 0 0 1 |

接下来的问题就是+1 操作了

                       | 1 1 0 0 |       

[ 1,B,C,D ]  X  | 0 1 0 0 |  =>[ 1,B+1,C,D ]

                       | 0 0 1 0 |       

                       | 0 0 0 1 |

然后用矩阵的快速幂就可以了。
#include<iostream>
#include<string.h>
#include<cstdio>
#define MAXN 111
using namespace std;typedef long long ll;
int n,m,k;
struct node{ll ma[MAXN][MAXN];
};node matrix,res;node matriXmult( node a,node b )
{node c;memset( c.ma,0,sizeof(c.ma) );for( int i=0;i<=n;i++ )for( int k=0;k<=n;k++ )if( a.ma[i][k] )for( int j=0;j<=n;j++ )c.ma[i][j]+=a.ma[i][k]*b.ma[k][j];return c;
}int main()
{while( scanf("%d%d%d",&n,&m,&k)&&n|k|m ){memset( matrix.ma,0,sizeof(matrix.ma) );for( int i=0;i<=n;i++ )matrix.ma[i][i]=1;while( k-- ){char command;int x,y;scanf( "\n%c",&command );if( command=='g' ){scanf( "%d",&x );matrix.ma[0][x]++;}else if( command=='e' ){scanf( "%d",&x );for( int i=0;i<=n;i++ )matrix.ma[i][x]=0;}else if( command=='s' ){scanf( "%d %d",&x,&y );for( int i=0;i<=n;i++ )swap( matrix.ma[i][x],matrix.ma[i][y] );}}memset( res.ma,0,sizeof(res.ma) );for( int i=0;i<=n;i++ )res.ma[i][i]=1;for( int i=0;i<31;i++ ){if( m&(1<<i) )res=matriXmult( res,matrix );matrix=matriXmult( matrix,matrix );}printf( "%I64d",res.ma[0][1] );for( int i=2;i<=n;i++ )printf( " %I64d",res.ma[0][i] );putchar('\n');}return 0;
}