题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1122
四个机器人a b c d,在2 * 2的方格里,一开始四个机器人分别站在4个格子上,每一步机器人可以往临近的一个格子移动或留在原地(同一个格子可以有多个机器人停留),经过n步后有多少种不同的走法,使得每个毯子上都有1机器人停留。由于方法数量巨大,输出 Mod 10^9 + 7的结果。
如何抽象为矩阵?
机器人在位置i时,其可以抵达三个位置,有一个不能抵达的对角位
矩阵A:
1 0 1 1
0 1 1 1
1 1 1 0
1 1 0 1
令第一行和第二行为对角,则位置一与位置二不能互相直达,第三行和第四行同理。
实际含义:
A[i][j]表示开始在位置i的机器人,经过一次移动,到达位置j的方案数。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stack>
#include<map>
#include<vector>
#include<queue>
#include<set>
#include<iomanip>
#include<cctype>
using namespace std;
const int MAXN=2e5+5;
const int INF=1<<30;
const long long mod=1e9+7;
#define ll long long
#define edl putchar('\n')
#define sscc ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define FORLL(i,a,b) for(ll i=a;i<=b;i++)
#define ROFLL(i,a,b) for(ll i=a;i>=b;i--)
#define mst(a) memset(a,0,ssizeof(a))
#define mstn(a,n) memset(a,n,ssizeof(a))
#define zero(x)(((x)>0?(x):-(x))<eps)
const int ssize=4;
struct Matrix
{
ll a[ssize][ssize];
Matrix()
{
memset(a,0,sizeof(a));
}
void init()
{
for(int i=0;i<ssize;i++)
for(int j=0;j<ssize;j++)
a[i][j]=(i==j);
}
Matrix operator + (const Matrix &B)const
{
Matrix C;
for(int i=0;i<ssize;i++)
for(int j=0;j<ssize;j++)
C.a[i][j]=(a[i][j]+B.a[i][j])%mod;
return C;
}
Matrix operator * (const Matrix &B)const
{
Matrix C;
for(int i=0;i<ssize;i++)
for(int k=0;k<ssize;k++)
for(int j=0;j<ssize;j++)
C.a[i][j]=(C.a[i][j]+1LL*a[i][k]*B.a[k][j])%mod;
return C;
}
Matrix operator ^ (const ll &t)const
{
Matrix A=(*this),res;
res.init();
ll p=t;
while(p)
{
if(p&1)res=res*A;
A=A*A;
p>>=1;
}
return res;
}
};
int main()
{
Matrix a;
FOR(i,0,3)
FOR(j,0,3)
a.a[i][j]=1;
a.a[1][0]=a.a[0][1]=a.a[3][2]=a.a[2][3]=0;
ll k,ans=0;
cin>>k;
a=a^k;
FOR(u,0,3)
FOR(i,0,3)
FOR(o,0,3)
FOR(p,0,3)
if(u!=i&&u!=o&&u!=p&&i!=o&&i!=p&&o!=p)
{
ans=(ans+(((a.a[0][u]*a.a[1][i])%mod*a.a[2][o])%mod*a.a[3][p])%mod)%mod;
}
cout<<ans<<endl;
}