[CH3401]石头游戏
Description
Solution
因为\(gcd(1,2,3,4,5,6)=60\),所以每\(60s\)内的变换是固定的,可以用\(60\)个矩阵表示,其中\(\forall x\in[1,60]\),令\(A[x][0][0]=1\),作为一个源源不断的常数来源
\(F[i]\)为行从\(0\)到\(0\),列从\(0\)到\(n\ast m\)的矩阵,表示第\(i\)秒的状态,其中\(F[0][0]=1\)
使\(t=60*p+q\),令\(A\)为\(60\)个矩阵相乘,\(F[0]\ast A^p*\prod^{q}_{i=1}A[i]\)则为最终矩阵
在这个矩阵里找最大值即可
Code
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define num(x, y) ((x - 1) * m + y)
struct Mat {
ll x, y;
ll val[65][65];
} f[61];
Mat operator * (const Mat &a, const Mat &b) {
Mat c;
c.x = a.x;
c.y = b.y;
for (register ll i = 0; i <= c.x; i++)
for (register ll j = 0; j <= c.y; j++) {
c.val[i][j] = 0;
for (register ll k = 0; k <= a.y; k++)
c.val[i][j] += a.val[i][k] * b.val[k][j];
}
return c;
}
ll n, m, t, act, X, Y, ans;
ll c[101], Len[101];
char str[101], s[101][101];
Mat a, HSH;
inline ll read() {
ll s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
Mat Pow(Mat a, int k) {
Mat ans;
ans.x = 64, ans.y = 64;
for (register ll i = 0; i <= 64; i++)
for (register ll j = 0; j <= 64; j++)
if (i == j) ans.val[i][j] = 1;
else ans.val[i][j] = 0;
while (k) {
if (k & 1) ans = ans * a;
a = a * a;
k >>= 1;
}
return ans;
}
int main() {
n = read(), m = read(), t = read(), act = read();
for (register ll i = 1; i <= n; i++) {
scanf("%s", str + 1);
for (register ll j = 1; j <= m; j++)
c[num(i, j)] = (str[j] ^ 48);
}
for (register ll i = 0; i < act; i++) {
scanf("%s", s[i] + 1);
Len[i] = strlen(s[i] + 1);
}
a.x = 0, a.y = 64;
a.val[0][0] = 1;
for (register ll k = 1; k <= 60; k++) {
f[k].x = 64;
f[k].y = 64;
f[k].val[0][0] = 1;
for (register ll i = 1; i <= n; i++)
for (register ll j = 1; j <= m; j++) {
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '0') f[k].val[0][num(i, j)] = 0, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '1') f[k].val[0][num(i, j)] = 1, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '2') f[k].val[0][num(i, j)] = 2, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '3') f[k].val[0][num(i, j)] = 3, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '4') f[k].val[0][num(i, j)] = 4, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '5') f[k].val[0][num(i, j)] = 5, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '6') f[k].val[0][num(i, j)] = 6, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '7') f[k].val[0][num(i, j)] = 7, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '8') f[k].val[0][num(i, j)] = 8, f[k].val[num(i, j)][num(i, j)] = 1;
if (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == '9') f[k].val[0][num(i, j)] = 9, f[k].val[num(i, j)][num(i, j)] = 1;
if (i > 1 && (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == 'N')) f[k].val[num(i, j)][num(i - 1, j)] = 1;
if (j > 1 && (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == 'W')) f[k].val[num(i, j)][num(i, j - 1)] = 1;
if (i < n && (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == 'S')) f[k].val[num(i, j)][num(i + 1, j)] = 1;
if (j < m && (s[c[num(i, j)]][(k - 1) % (Len[c[num(i, j)]]) + 1] == 'E')) f[k].val[num(i, j)][num(i, j + 1)] = 1;
}
}
HSH.x = 64, HSH.y = 64;
for (register ll i = 0; i <= 64; i++)
HSH.val[i][i] = 1;
for (register ll i = 1; i <= 60; i++)
HSH = HSH * f[i];
X = t / 60;
Y = t % 60;
if (X) a = a * Pow(HSH, X);
for (register ll i = 1; i <= Y; i++)
a = a * f[i];
for (register ll i = 1; i <= 64; i++)
ans = max(ans, a.val[0][i]);
printf("%lld", ans);
return 0;
}
只要有想见的人,就不是孤身一人了。