「游记」The 2023 ICPC Asia Regionals Online Contest (1)
N/A
考试一开始在找签到题(脑子有病吧
最后还是跟着榜做的题。
队友看了 \(L,D\),我看了 \(A\),写完 \(D\) 机房断网了,看别人知道了必须要重启电脑(此时距断网已经过了二十分钟左右了),重启电脑后交了 \(D\) 此时还是校内三题队第一,校内排名也还不错。
继续跟榜做,写 \(D\) 的时候队友开了 \(J\),我就去看了 \(I\),写了三道题的代码名次还不错有点懈怠了没秒了 \(I\) 是我的错。写完 \(I\) 有各种各样 \(bug\) 就虚拟打印出来去找 \(bug\) 让队友写 \(J\) 了。找到了 \(I\) 的问题等队友写完 \(J\) 我上去改的时候忘改了一处,然后一整场没调出来,队友 \(J\) 也没调出来,怎么绘世鸭。
最后获得了校倒数第一的好成绩,成功被 \(23\) 级吊打。
题解
I
简单 \(dp\),\(f[i][j][0/1][0/1][0/1]\) 表示前 \(i\) 位密码且第 \(i\) 位字符为 \(j\),是否(\(0/1\))满足出现过大写字母,是否(\(0/1\))满足出现过小写字母,是否(\(0/1\))满足出现过数字,有多少种合法情况。空间只给了 \(32MB\),使用滚动数组就行了。转移就是分类讨论。
考场上没想到把后三维用状压压成一维,想到的话这题会不会就调出来了呢。
#include <bits/stdc++.h>
int n;
std::string s;
int cti[518], itc[101];
const int mod = 998244353;
long long in[2][2][2], ex[518][2][2][2], f[2][101][2][2][2];
int main() {
scanf("%d", &n);
std::cin >> s;
int cnt = 0;
for (int i = '0'; i <= '9'; ++i) cti[i] = cnt, itc[cnt++] = i;
for (int i = 'a'; i <= 'z'; ++i) cti[i] = cnt, itc[cnt++] = i;
for (int i = 'A'; i <= 'Z'; ++i) cti[i] = cnt, itc[cnt++] = i;
int now = 0;
if ((s[0] >= 'A' && s[0] <= 'Z') || (s[0] >= '0' && s[0] <= '9')) {
if (s[0] >= 'A' && s[0] <= 'Z') f[0][cti[s[0]]][1][0][0] = 1;
else f[0][cti[s[0]]][0][0][1] = 1;
} else if (s[0] >= 'a' && s[0] <= 'z') {
f[0][cti[s[0]]][0][1][0] = 1;
f[0][cti[s[0]] + 26][1][0][0] = 1;
} else {
for (int i = 0; i < cnt; ++i) {
if (itc[i] >= '0' && itc[i] <= '9') f[0][i][0][0][1] = 1;
else if (itc[i] >= 'a' && itc[i] <= 'z') f[0][i][0][1][0] = 1;
else f[0][i][1][0][0] = 1;
}
}
for (int j = 1; j < n; ++j) {
in[0][0][0] = 0;
in[0][0][1] = 0;
in[0][1][0] = 0;
in[0][1][1] = 0;
in[1][0][0] = 0;
in[1][0][1] = 0;
in[1][1][0] = 0;
in[1][1][1] = 0;
for (int i = 0; i <= cnt; ++i) {
in[0][0][0] = (in[0][0][0] + f[now][i][0][0][0]) % mod;
in[0][0][1] = (in[0][0][1] + f[now][i][0][0][1]) % mod;
in[0][1][0] = (in[0][1][0] + f[now][i][0][1][0]) % mod;
in[0][1][1] = (in[0][1][1] + f[now][i][0][1][1]) % mod;
in[1][0][0] = (in[1][0][0] + f[now][i][1][0][0]) % mod;
in[1][0][1] = (in[1][0][1] + f[now][i][1][0][1]) % mod;
in[1][1][0] = (in[1][1][0] + f[now][i][1][1][0]) % mod;
in[1][1][1] = (in[1][1][1] + f[now][i][1][1][1]) % mod;
}
for (int i = 0; i < cnt; ++i) {
ex[i][0][0][0] = (in[0][0][0] - f[now][i][0][0][0] + 2 * mod) % mod;
ex[i][0][0][1] = (in[0][0][1] - f[now][i][0][0][1] + 2 * mod) % mod;
ex[i][0][1][0] = (in[0][1][0] - f[now][i][0][1][0] + 2 * mod) % mod;
ex[i][0][1][1] = (in[0][1][1] - f[now][i][0][1][1] + 2 * mod) % mod;
ex[i][1][0][0] = (in[1][0][0] - f[now][i][1][0][0] + 2 * mod) % mod;
ex[i][1][0][1] = (in[1][0][1] - f[now][i][1][0][1] + 2 * mod) % mod;
ex[i][1][1][0] = (in[1][1][0] - f[now][i][1][1][0] + 2 * mod) % mod;
ex[i][1][1][1] = (in[1][1][1] - f[now][i][1][1][1] + 2 * mod) % mod;
}
now ^= 1;
for (int i = 0; i < cnt; ++i) {
f[now][i][0][0][0] = 0, f[now][i][0][0][1] = 0, f[now][i][0][1][0] = 0, f[now][i][0][1][1] = 0;
f[now][i][1][0][0] = 0, f[now][i][1][0][1] = 0, f[now][i][1][1][0] = 0, f[now][i][1][1][1] = 0;
}
if ((s[j] >= 'A' && s[j] <= 'Z') || (s[j] >= '0' && s[j] <= '9')) {
if (s[j] >= 'A' && s[j] <= 'Z') {
for (int i = 0; i < cnt; ++i) {
if (itc[i] == s[j]) continue;
if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j]]][1][0][0] += f[now ^ 1][i][0][0][0]) %= mod;
if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][0][0][1]) %= mod;
if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][0][1][0]) %= mod;
if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j]]][1][0][0] += f[now ^ 1][i][1][0][0]) %= mod;
if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][1][0][1]) %= mod;
if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][1][1][0]) %= mod;
if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
}
} else {
for (int i = 0; i < cnt; ++i) {
if (itc[i] == s[j]) continue;
if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j]]][0][0][1] += f[now ^ 1][i][0][0][0]) %= mod;
if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j]]][0][0][1] += f[now ^ 1][i][0][0][1]) %= mod;
if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][1][0]) %= mod;
if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][1][0][0]) %= mod;
if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j]]][1][0][1] += f[now ^ 1][i][1][0][1]) %= mod;
if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][0]) %= mod;
if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
}
}
} else if (s[j] >= 'a' && s[j] <= 'z') {
for (int i = 0; i < cnt; ++i) {
if (itc[i] != s[j]) {
if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j]]][0][1][0] += f[now ^ 1][i][0][0][0]) %= mod;
if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][0][1]) %= mod;
if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j]]][0][1][0] += f[now ^ 1][i][0][1][0]) %= mod;
if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j]]][0][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][1][0][0]) %= mod;
if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][0][1]) %= mod;
if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j]]][1][1][0] += f[now ^ 1][i][1][1][0]) %= mod;
if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j]]][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
}
if (itc[i] != s[j] - 'a' + 'A') {
if (f[now ^ 1][i][0][0][0]) (f[now][cti[s[j] - 'a' + 'A']][1][0][0] += f[now ^ 1][i][0][0][0]) %= mod;
if (f[now ^ 1][i][0][0][1]) (f[now][cti[s[j] - 'a' + 'A']][1][0][1] += f[now ^ 1][i][0][0][1]) %= mod;
if (f[now ^ 1][i][0][1][0]) (f[now][cti[s[j] - 'a' + 'A']][1][1][0] += f[now ^ 1][i][0][1][0]) %= mod;
if (f[now ^ 1][i][0][1][1]) (f[now][cti[s[j] - 'a' + 'A']][1][1][1] += f[now ^ 1][i][0][1][1]) %= mod;
if (f[now ^ 1][i][1][0][0]) (f[now][cti[s[j] - 'a' + 'A']][1][0][0] += f[now ^ 1][i][1][0][0]) %= mod;
if (f[now ^ 1][i][1][0][1]) (f[now][cti[s[j] - 'a' + 'A']][1][0][1] += f[now ^ 1][i][1][0][1]) %= mod;
if (f[now ^ 1][i][1][1][0]) (f[now][cti[s[j] - 'a' + 'A']][1][1][0] += f[now ^ 1][i][1][1][0]) %= mod;
if (f[now ^ 1][i][1][1][1]) (f[now][cti[s[j] - 'a' + 'A']][1][1][1] += f[now ^ 1][i][1][1][1]) %= mod;
}
}
} else {
for (int i = 0; i < cnt; ++i) {
if(itc[i] >= 'A' && itc[i] <= 'Z') {
f[now][i][1][0][0] = (ex[i][1][0][0] + ex[i][0][0][0]) % mod;
f[now][i][1][0][1] = (ex[i][1][0][1] + ex[i][0][0][1]) % mod;
f[now][i][1][1][0] = (ex[i][1][1][0] + ex[i][0][1][0]) % mod;
f[now][i][1][1][1] = (ex[i][1][1][1] + ex[i][0][1][1]) % mod;
} else if (itc[i] >= 'a' && itc[i] <= 'z'){
f[now][i][0][1][0] = (ex[i][0][1][0] + ex[i][0][0][0]) % mod;
f[now][i][0][1][1] = (ex[i][0][1][1] + ex[i][0][0][1]) % mod;
f[now][i][1][1][0] = (ex[i][1][1][0] + ex[i][1][0][0]) % mod;
f[now][i][1][1][1] = (ex[i][1][1][1] + ex[i][1][0][1]) % mod;
} else {
f[now][i][0][0][1] = (ex[i][0][0][1] + ex[i][0][0][0]) % mod;
f[now][i][0][1][1] = (ex[i][0][1][1] + ex[i][0][1][0]) % mod;
f[now][i][1][0][1] = (ex[i][1][0][1] + ex[i][1][0][0]) % mod;
f[now][i][1][1][1] = (ex[i][1][1][1] + ex[i][1][1][0]) % mod;
}
}
}
}
if ((s[n - 1] >= 'A' && s[n - 1] <= 'Z') || (s[n - 1] >= '0' && s[n - 1] <= '9')) {
std::cout << f[now][cti[s[n - 1]]][1][1][1] % mod << '\n';
} else if (s[n - 1] >= 'a' && s[n - 1] <= 'z') {
std::cout << (f[now][cti[s[n - 1]]][1][1][1] + f[now][cti[s[n - 1] - 'a' + 'A']][1][1][1]) % mod << '\n';
} else {
long long ans = 0;
for (int i = 0; i < cnt; ++i) ans = (ans + f[now][i][1][1][1]) % mod;
std::cout << ans << '\n';
}
return 0;
}