USACO24DecB
前言
我要嘲讽所有没有AK铜组的人!
A. Roundabount Rounding
用时:思路 20s,调试 60min
注意到若首位小于 \(4\),则两种方法都只能舍到 \(0\);若首位大于 \(4\),则两种方法都只能入到 \(10^P\)。那么合法的数首位一定为 \(4\)
然后我们去掉首位,将剩下的数递归处理,发现合法的数一定形如:\(4\dots4f_0f_1\dots f_r\),其中 \(f_0>4,\forall i \in[1,r],f_i\in[0,9]\)
可以把所有一位数、两位数……的答案预处理出来,就只需要考虑 \(P\) 位数的情况了
枚举从哪一位开始不是 \(4\),让后用一个类似计数 DP 思想的 \(\text{Limit}\),判断 \(n\) 的前几位是否全是 \(4\)。如果是,则接下来的数就只能是 \(50\dots 0\sim\) \(n\) 的后几位;否则为 \(50\dots 0\sim99\dots9\)
// BLuemoon_
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
LL t, n, ans, p[15] = {0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999ll, 999999999ll, 9999999999ll}, f[15] = {0, 0, 5, 55, 555, 5555, 55555, 555555, 5555555, 55555555ll, 555555555ll, 5555555555ll};
int main() {
for (cin >> t; t; t--, ans = 0) {
cin >> n;
for (LL i = 1; i <= 10; i++) {
if (n > p[i]) {
ans += f[i];
} else {
LL Lm = 1, tmp = 5 * (p[i - 1] + 1), u = 0;
for (LL j = i; j - 1; j--) {
LL x = (n / (p[j - 1] + 1)) % 10, cnt = 0;
if (Lm && x < 4) {
break;
}
tmp -= 5 * (p[j - 2] + 1);
Lm &= (x == 4);
for (LL k = j - 1; k; k--) {
(cnt *= 10) += (Lm ? (n / (p[k - 1] + 1)) % 10 : 9);
}
u += 4 * (p[j - 1] + 1), cnt += u;
ans += (cnt >= tmp) * (cnt - tmp + 1);
}
cout << ans << '\n';
break;
}
}
}
return 0;
}
B. Farmer John's Cheese Block
用时:思路 1s,代码 90s
开三个二维数组记录在 \(x,y,z\) 方向剩余奶酪块数量。对于每组询问,在三个方向上更新数量和答案即可
// BLuemoon_
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const int kMaxN = 1e3 + 5;
LL n, q, x, y, z, ans, e[kMaxN][kMaxN], f[kMaxN][kMaxN], g[kMaxN][kMaxN];
int main() {
for (cin >> n >> q, fill(e[0], e[n + 2], n), fill(f[0], f[n + 2], n), fill(g[0], g[n + 2], n); q; q--) {
cin >> x >> y >> z, ans += !--e[y][z] + !--f[x][z] + !--g[x][y], cout << ans << '\n';
}
return 0;
}
C. It's Mooin' Time
用时:思路 2min,代码 15min
枚举修改的位数和字母,由于修改操作只会修改相邻三个字符串,可以记录被修改的字符串,判断修改后出现数量是否大于 \(F\) 即可
// BLuemoon_
#include <bits/stdc++.h>
using namespace std;
int n, m, ans;
string s, tmp;
unordered_map<string, int> mp;
set<string> f, g;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n >> m >> s, s = ' ' + s, tmp = s;
for (int i = 1; i <= n - 2; i++) {
if (s[i] != s[i + 1] && s[i + 1] == s[i + 2]) {
mp[s.substr(i, 3)]++;
}
}
for (auto i : mp) {
(i.second >= m) && (f.insert(i.first), 0);
}
for (int i = 1; i <= n; i++) {
for (char c = 'a'; c <= 'z'; c++) {
tmp[i] = c, g.clear();
for (int j = i - 2; j <= i; j++) {
if (j >= 1 && j + 2 <= n) {
if (!(tmp[j] != tmp[j + 1] && tmp[j + 1] == tmp[j + 2]) && s[j] != s[j + 1] && s[j + 1] == s[j + 2]) {
mp[s.substr(j, 3)]--;
}
if (!(s[j] != s[j + 1] && s[j + 1] == s[j + 2]) && tmp[j] != tmp[j + 1] && tmp[j + 1] == tmp[j + 2]) {
mp[tmp.substr(j, 3)]++, g.insert(tmp.substr(j, 3));
}
if (s[j] != s[j + 1] && s[j + 1] == s[j + 2] && tmp[j] != tmp[j + 1] && tmp[j + 1] == tmp[j + 2]) {
mp[tmp.substr(j, 3)]++, mp[s.substr(j, 3)]--, g.insert(tmp.substr(j, 3));
}
}
}
for (string t : g) {
(mp[t] >= m) && (f.insert(t), 0);
}
for (int j = i - 2; j <= i; j++) {
if (j >= 1 && j + 2 <= n) {
if (!(tmp[j] != tmp[j + 1] && tmp[j + 1] == tmp[j + 2]) && s[j] != s[j + 1] && s[j + 1] == s[j + 2]) {
mp[s.substr(j, 3)]++;
}
if (!(s[j] != s[j + 1] && s[j + 1] == s[j + 2]) && tmp[j] != tmp[j + 1] && tmp[j + 1] == tmp[j + 2]) {
mp[tmp.substr(j, 3)]--;
}
if (s[j] != s[j + 1] && s[j + 1] == s[j + 2] && tmp[j] != tmp[j + 1] && tmp[j + 1] == tmp[j + 2]) {
mp[tmp.substr(j, 3)]--, mp[s.substr(j, 3)]++;
}
}
}
tmp[i] = s[i];
}
}
cout << f.size() << '\n';
for (string t : f) {
cout << t << '\n';
}
return 0;
}

浙公网安备 33010602011771号