51nod 1122 机器人走方格 V4(矩阵快速幂)

来源:互联网 发布:合并多张表sql语句 编辑:程序博客网 时间:2024/05/29 13:14

1122 机器人走方格 V4
基准时间限制: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;}









原创粉丝点击