hdu 2232 机器人的舞蹈 矩阵快速幂
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2232
矩阵很神奇。
相信大家不出意外,对于下面这个矩阵还是好构造的。
第0排代表第0号格子的机器人,可以到达个格子,可见2号格子是不可达的。
这个矩阵的N次幂,就是机器人走多少步形成的局面。
上面矩阵的2次幂:
可以得到上面的矩阵,这是什么意思呢?
第0排的3表示0号格子的机器人通过2步有3种方法到0号格子。
哪三种?0-0-0,0-1-0,0-3-0。就这三种。
同样每个格子的数也代表了不同的意义。
那么题中所求的最终回到每个格子一个机器人的状态。
也就是在这个矩阵中不同行不同列放置4个机器人的可能情况的总数
用dfs就可以了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<string> 3 #include<cstdio> 4 using namespace std; 5 6 struct node 7 { 8 int m[4][4]; 9 }res,temp,mod; 10 11 int sum; 12 13 node matriXmult( node a,node b ) 14 { 15 node c; 16 int i,j,k; 17 memset( c.m,0,sizeof(c.m) ); 18 for( i=0;i<4;i++ ) 19 for( j=0;j<4;j++ ) 20 for( k=0;k<4;k++ ) 21 c.m[i][j]+=a.m[i][k]*b.m[k][j]; 22 for( i=0;i<4;i++ ) 23 for( j=0;j<4;j++ ) 24 c.m[i][j]%=9937; 25 return c; 26 } 27 28 void matrix_Power(int n) 29 { 30 int i,j; 31 memset( res.m,0,sizeof(res.m) ); 32 memset( temp.m,0,sizeof(temp.m) ); 33 for( i=0;i<4;i++ ) 34 { 35 res.m[i][i]=1; 36 for( j=0;j<4;j++ ) 37 temp.m[i][j]=mod.m[i][j]; 38 } 39 for( i=0;i<31;i++ ) 40 { 41 if( n&(1<<i) ) 42 res=matriXmult(res,temp); 43 temp=matriXmult(temp,temp); 44 } 45 } 46 47 bool vis[4]; 48 void dfs( int col,int row,int x ) 49 { 50 int i; 51 if( x==0 ) 52 return ; 53 x=(x*res.m[row][col])%9937; 54 if( row>2 ) 55 sum=(sum+x)%9937; 56 for( i=0;i<4;i++ ) 57 { 58 if( vis[i]==false ) 59 { 60 vis[i]=true; 61 dfs( i,row+1,x ); 62 vis[i]=false; 63 } 64 } 65 } 66 67 int main() 68 { 69 int n; 70 int i,j; 71 for( i=0;i<4;i++ ) 72 for( j=0;j<4;j++ ) 73 mod.m[i][j]=1; 74 mod.m[0][2]=0; 75 mod.m[1][3]=0; 76 mod.m[2][0]=0; 77 mod.m[3][1]=0; 78 while( scanf("%d",&n)!=EOF ) 79 { 80 matrix_Power(n); 81 sum=0; 82 int x; 83 memset( vis,0,sizeof(vis) ); 84 for( int i=0;i<4;i++ ) 85 { 86 x=1; 87 vis[i]=true; 88 dfs( i,0,x ); 89 vis[i]=false; 90 } 91 printf( "%d\n",sum ); 92 } 93 return 0; 94 }