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就可以了。

View Code
 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 }

 

posted @ 2012-05-06 17:06  我们一直在努力  阅读(422)  评论(0编辑  收藏  举报