基准时间限制:1 秒 空间限制:131072 KB 分值: 160
难度:6级算法题
四个机器人a b c d,在2 * 2的方格里,一开始四个机器人分别站在4个格子上,每一步机器人可以往临近的一个格子移动或留在原地(同一个格子可以有多个机器人停留),经过n步后有多少种不同的走法,使得每个毯子上都有1机器人停留。由于方法数量巨大,输出 Mod 10^9 + 7的结果。
Input
输入1个数N(0 <= N <= 10^9)
Output
输出走法的数量 Mod 10^9 + 7
Input示例
1
Output示例
9
解:这题有个很关键的条件就是每一个格子可以容纳多个机器人,那么直接求出每个机器人可以走的方法数的转移矩阵 用矩阵快速幂计算,最后统计合法数量即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
#include <vector>
using namespace std;
typedef long long LL;
typedef vector<LL>a;
typedef vector<a>b;
const LL mod = 1000000007;
b jie(b m, b n)
{
b z(m.size(),a(n[0].size()));
for(int i=0; i<m.size(); i++)
{
for(int k=0; k<n.size(); k++)
{
for(int j=0; j<n[0].size(); j++)
{
z[i][j]=(z[i][j]+m[i][k]*n[k][j]%mod)%mod;
}
}
}
return z;
}
b Pow(b x,LL n,int m)
{
b y(m,a(m));
for(int i=0; i<m; i++)
y[i][i]=1;
while(n>0)
{
if(n&1)
{
y=jie(y,x);
}
x=jie(x,x);
n>>=1;
}
return y;
}
int main()
{
LL m, n;
scanf("%lld",&n);
if(n==0)
{
printf("1\n");
return 0;
}
b x(4,a(4));
x[0][0]=1,x[0][1]=1,x[0][2]=0,x[0][3]=1;
x[1][0]=1,x[1][1]=1,x[1][2]=1,x[1][3]=0;
x[2][0]=0,x[2][1]=1,x[2][2]=1,x[2][3]=1;
x[3][0]=1,x[3][1]=0,x[3][2]=1,x[3][3]=1;
x = Pow(x, n, 4);
b y(4,a(4));
y[0][0]=1,y[0][1]=0,y[0][2]=0,y[0][3]=0;
y[1][0]=0,y[1][1]=1,y[1][2]=0,y[1][3]=0;
y[2][0]=0,y[2][1]=0,y[2][2]=1,y[2][3]=0;
y[3][0]=0,y[3][1]=0,y[3][2]=0,y[3][3]=1;
y=jie(y,x);
LL sum=0;
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(i==j) continue;
for(int k=0;k<4;k++)
{
if(k==i||k==j) continue;
for(int p=0;p<4;p++)
{
if(p==i||p==j||p==k) continue;
sum=(sum+((y[0][i]*y[1][j]%mod)*(y[2][k]*y[3][p]%mod)%mod)%mod)%mod;
}
}
}
}
printf("%lld\n",sum%mod);
return 0;
}