机器人的舞蹈

来源:互联网 发布:小礼服 知乎 编辑:程序博客网 时间:2024/04/27 17:10
Problem Description
一天四个不同的机器人a、b、c和d在一张跳舞毯上跳舞,这是一张特殊的跳舞毯,他由4个正方形毯子组成一个大的正方形毯子,一开始四个机器人分别站在4块毯子上,舞蹈的每一步机器人可以往临近(两个毯子拥有同一条边视为临近)的一个毯子移动或停留在原来的毯子(同一块毯子可以有多个机器人停留),这个时候机器人的制造者你想知道经过n步的移动有多少种方式可以让每个毯子上都有机器人停留。
Input
对于每组数据输入一个整数n(0<=n<=100)
Output
对于每组输入输出一个整数表示方法种数,种数可能很大请对9937取模。
Sample Input
1
Sample Output
9
最开始看到这个题目的时候,我首先想到的是用回溯法来实现,但是做了很久发现递归比较深,也总得不到理想的结果,就在网上搜索了一下,看到了矩阵乘法。
首先定义一个三维矩阵map[m][i][j],其含义规定为:从i到j,经过m步,一共有map[m][i][j]种方法。即在第m步,有map[m][i][j]个方法从i到j。利用矩阵乘法,map[m]=map[m-1]矩阵乘以map[1]。那么由map[1]就可以推导出map[101]了。
如果我们假定四个正方形定义如下:
1  2
3  4
那么map[1][4][4]={1,1,1,0,   1,1,0,1,    1,0,1,1,    0,1,1,1,};第一行为0表示1到4是不行的。
推导出所有的map之后就好办了,我们只要找出四个都为1的情况,即经过n步后,1到1,2到2,3到3,4到4,或者1到2,2到3,3到4,4到1,通过循环,找出所有的情况,就能得出结果了。代码如下:
#include <iostream>#define mod9937using namespace std;int a[4][4]={1,1,1,0,1,1,0,1,1,0,1,1,0,1,1,1,};int map[102][4][4];int main(){int i,j,k,l;for(i=1;i<102;i++){if(i==1){for(j=0;j<4;j++)for(k=0;k<4;k++)map[i][j][k]=a[j][k];}else{for(j=0;j<4;j++){for(k=0;k<4;k++){map[i][j][k]=0;for(l=0;l<4;l++){map[i][j][k]=map[i][j][k]+(map[i-1][j][l]*map[1][l][k])%mod;}}}}}int n;while(cin>>n){int rt=0;for(i=0;i<4;i++){for(j=0;j<4;j++){for(k=0;k<4;k++){for(l=0;l<4;l++){if(i==j || i==k || i==l || j==k || j==l || k==l) continue;rt=(rt+(map[n][0][i]*map[n][1][j]*map[n][2][k]*map[n][3][l])%mod)%mod;}}}}cout<<rt<<endl;}return 0;}
 
如果有不妥的地方,还望指出,谢谢。
0 0
原创粉丝点击