考慮到$lcm(1,2,3,4,5,6)=60$,所以操作序列每60秒一個迴圈。
將操作表示成轉移矩陣的形式,預處理出前60秒的轉移矩陣以及它們的乘積$B$。
那麼t秒的轉移矩陣為前$t\bmod 60$個轉移矩陣的乘積乘以$B^{\lfloor\frac{t}{60}\rfloor}$。
用矩陣快速冪加速計算即可。
#include<cstdio> #include<cstring> #define rep(i,n) for(int i=0;i<n;i++) #define P 65 typedef long long ll; int n,m,t,q,i,j,k,x,y,N,id[P][P],a[P][P],l[P];char s[P],b[P][P],c;ll ans; struct mat{ ll a[P][P]; mat(){rep(i,P)rep(j,P)a[i][j]=0;} inline mat operator*(mat b){ mat c; rep(i,N)rep(j,N)rep(k,N)c.a[i][j]+=a[i][k]*b.a[k][j]; return c; } }one,A[P],pre[P],B,C,D; int main(){ scanf("%d%d%d%d",&n,&m,&t,&q); for(i=1;i<=n;i++)for(scanf("%s",s+1),j=1;j<=m;j++)id[i][j]=++N,a[i][j]=s[j]-'0';N++; for(i=0;i<q;i++)scanf("%s",b[i]+1),l[i]=std::strlen(b[i]+1),b[i][0]=b[i][l[i]]; rep(i,N)one.a[i][i]=1; for(pre[0]=one,i=1;i<=60;i++){ A[i].a[0][0]=1; for(j=1;j<=n;j++)for(k=1;k<=m;k++){ c=b[a[j][k]][i%l[a[j][k]]]; if(c>='0'&&c<='9')A[i].a[id[j][k]][0]=c-'0',A[i].a[id[j][k]][id[j][k]]++; if(c=='N'){ x=j-1,y=k; if(x>=1)A[i].a[id[x][y]][id[j][k]]++; } if(c=='S'){ x=j+1,y=k; if(x<=n)A[i].a[id[x][y]][id[j][k]]++; } if(c=='W'){ x=j,y=k-1; if(y>=1)A[i].a[id[x][y]][id[j][k]]++; } if(c=='E'){ x=j,y=k+1; if(y<=m)A[i].a[id[x][y]][id[j][k]]++; } } pre[i]=A[i]*pre[i-1]; } for(B=pre[60],C=one,k=t/60;k;k>>=1,B=B*B)if(k&1)C=C*B; for(D.a[0][0]=1,D=pre[t%60]*C*D,i=1;i<N;i++)if(ans<D.a[i][0])ans=D.a[i][0]; return printf("%lld",ans),0; }