记录编号 584993 评测结果 AAAAAA
题目名称 石头游戏 最终得分 100
用户昵称 Gravatar┭┮﹏┭┮ 是否通过 通过
代码语言 C++ 运行时间 0.078 s
提交时间 2023-11-17 20:18:17 内存使用 6.63 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 12;
typedef long long ll;
ll n,m,k,q;
struct Matrix{
    ll a[66][66],n,m;
    void clear(){n = m = 0;memset(a,0,sizeof(a));}
    Matrix operator * (const Matrix x)const{
        Matrix y;y.clear();
        y.n = n,y.m = m;
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= m;j++)
                for(int k = 1;k <= m;k++)
                    y.a[i][j] = (y.a[i][j] + (a[i][k] * x.a[k][j]));
        return y;
    }
}c[66],f;
char op[N][N];
ll l[N],a[N][N];
ll id(ll x,ll y){
    return (x-1)*n+y;
}// 
int main(){
    freopen("marble.in","r",stdin);
    freopen("marble.out","w",stdout);
    scanf("%lld%lld%lld%lld",&n,&m,&k,&q);
    f.n = 1,f.m = n*m+1;
    f.a[1][n*m+1] = 1;
    for(int i = 1;i <= n;i++)
        for(int j = 1;j <= m;j++){
            char ch;cin>>ch;
            a[i][j] = ch - '0';// 
        }
    for(int i = 0;i < q;i++)scanf("%s",op[i]+1),l[i] = 1;
    //操作序列为6,1~6的最小公倍数为60,则可以以60为分界 
    for(int k = 1;k <= 60;k++){
        for(int i = 1;i <= n;i++){
            for(int j = 1;j <= m;j++){
                int u = a[i][j];
                char w = op[u][l[u]];
                if(w >= '0' && w <= '9')c[k].a[n*m+1][id(i,j)] = w - '0',c[k].a[id(i,j)][id(i,j)] = 1;//自己!! 
                else if(w == 'E' && j < m)c[k].a[id(i,j)][id(i,j+1)] = 1;
                else if(w == 'W' && j > 1)c[k].a[id(i,j)][id(i,j-1)] = 1;
                else if(w == 'N' && i > 1)c[k].a[id(i,j)][id(i-1,j)] = 1;
                else if(w == 'S' && i < n)c[k].a[id(i,j)][id(i+1,j)] = 1;
            }
        }//c[k]表示前k秒操作的转移矩阵 
        for(int i = 0;i < q;i++){
            if(l[i] + 1 > strlen(op[i]+1))l[i] = 1;
            else l[i]++;
        }//
        c[k].a[n*m+1][n*m+1] = 1;//常数1 
        c[k].n = c[k].m = n*m+1;
        if(k != 1)c[k] = c[k-1] * c[k];//前缀乘,不满足交换律 
    }
    ll u = k / 60;
    while(u){
        if(u & 1)f = f * c[60];
        c[60] = c[60] * c[60];
        u >>= 1;
    }
    u = k % 60;
    if(u)f = f * c[u];// 
    ll ans = 0;
    for(int i = 1;i <= n*m;i++)ans = max(f.a[1][i],ans);
    printf("%lld\n",ans);
    
    return 0;
    
}