51Nod-1122-机器人走方格 V4

来源:互联网 发布:网络连接图片 编辑:程序博客网 时间:2024/06/07 21:10

ACM模版

描述

描述

题解

最开始看这个题,半天没有看懂样例,后来发现原来这里的走一步是指四个机器人同时走一步,于是乎,这个可以用矩阵快速幂来解决,毕竟这种套路的题核心就是构造可达矩阵……至于可达矩阵的构造方案,有很多种,但是都是相似的,可以看看讨论区中大佬的构造方案,剩下的就么有啥可说的了。

这个忘了说一点,最开始提交只过了两组,其他都 WA 了,仔细查看代码发现是自己存在溢出问题,一个十分常见的问题,在取模的过程中因为不当操作导致溢出,这个太蠢了,错的有些二。

代码

#include <iostream>#include <cstring>/* *  矩阵快速幂 n*n矩阵的x次幂 */#define MAXN 5#define MOD 1000000007#define LL long longusing namespace std;int n, N;struct mat{    LL m[MAXN][MAXN];} unit; //  单元矩阵//  矩阵乘法mat operator * (mat a, mat &b){    mat ret;    memset(ret.m, 0, sizeof(ret.m));    for (int k = 0; k < n; k++)    {        for (int i = 0; i < n; i++)        {            if (a.m[i][k])            {                for (int j = 0; j < n; j++)                {                    ret.m[i][j] = (ret.m[i][j] + a.m[i][k] * b.m[k][j] % MOD) % MOD;                }            }        }    }    return ret;}void init_unit(){    n = 4;    for (int i = 0; i < MAXN; i++)    {        unit.m[i][i] = 1;    }}mat pow_mat(mat a, LL n){    mat ret = unit;    while (n)    {        if (n & 1)        {            ret = ret * a;        }        n >>= 1;        a = a * a;    }    return ret;}int main(){    init_unit();    cin >> N;    if (N == 0)    {        puts("1");        return 0;    }    mat a;    a.m[0][0] = 1, a.m[0][1] = 1, a.m[0][2] = 1, a.m[0][3] = 0;    a.m[1][0] = 1, a.m[1][1] = 1, a.m[1][2] = 0, a.m[1][3] = 1;    a.m[2][0] = 1, a.m[2][1] = 0, a.m[2][2] = 1, a.m[2][3] = 1;    a.m[3][0] = 0, a.m[3][1] = 1, a.m[3][2] = 1, a.m[3][3] = 1;    a = pow_mat(a, N);    LL ans = 0;    for (int i = 0; i < n; i++)    {        for (int j = 0; j < n; j++)        {            if (i == j)            {                continue;            }            for (int k = 0; k < n; k++)            {                if (k == i || k == j)                {                    continue;                }                for (int l = 0; l < n; l++)                {                    if (l == i || l == j || l == k)                    {                        continue;                    }                    ans += ((a.m[0][i] * a.m[1][j] % MOD) * (a.m[2][k] * a.m[3][l] % MOD)) % MOD;                    ans %= MOD;                }            }        }    }    printf("%lld\n", ans);    return 0;}