这场属实阴间。
A. Acacius and String
替换字符串 $s$ 中的 ?,使得出现且仅出现一次 abacaba。
分析
本题较为难写,因为很难判断恰好出现了一次。但是数据规模很小,可以采用非常暴力的写法。
一种想法是,枚举每个出现 abacaba 的位置 $i$,把当前 $s[i, i + 6]$ 中的 ? 设为给定串,这样就得到了字符串 $t$。
然后判断字符串 $t$ 中只出现了一次 abacaba,可以通过 substr 枚举所有长为 $6$ 的子串。
string what = "abacaba";
int N = what.length();
void solve() {
int n;
string s;
cin >> n >> s;
for (int i = 0; i <= n - N; i++) {
string tmp = s;
for (int j = 0; j < N; j++) {
if (tmp[i + j] == '?') {
tmp[i + j] = what[j];
}
}
for (int j = 0; j < tmp.length(); j++) {
if (tmp[j] == '?')
tmp[j] = 'z';
}
int cnt = 0;
for (int j = 0; j <= tmp.length() - N; j++) {
if (tmp.substr(j, N) == what)
cnt++;
}
if (cnt == 1) {
cout << "Yes\n" << tmp << "\n";
return;
}
}
cout << "No\n";
}
全部代码请看:Codeforces/CF1379/CF1379A.cpp。
B. Dubious Cyrpto
给定 $l,r,m$,找到正整数 $a,b,c,n$ 满足 $m = an + b - c$,且 $l \leqslant a,b,c \leqslant r$。
分析
反解 $n$ 得到
$$ \frac{m - (b - c)}{a} = n $$
我们可以把 $b - c$ 当作一个整体。注意到 $n$ 是正整数,说明 $m - (b - c)$ 必须要能够整除 $a$,而且 $a$ 的范围不是很大,因此我们可以枚举 $a$。
再注意到 $b-c$ 的范围是 $[l-r,r-l]$,即判断 $m \bmod a$ 是否在这个范围内。
void solve() {
ll l, r, m;
cin >> l >> r >> m;
for (ll a = l; a <= r; a++) {
int b_c = (m + r - l) % a - (r - l);
if (b_c > r - l)
continue;
if (b_c < 0)
cout << a << " " << (r + b_c) << " " << r << "\n";
else
cout << a << " " << (l + b_c) << " " << l << "\n";
break;
}
}
全部代码请看:Codeforces/CF1379/CF1379B.cpp。
C. Choosing flowers
对于 $n$ 种花,如果其中第 $i$ 种选择了 $x_i > 0$ 朵,那么其贡献是
$$ a_i + (x_i - 1) b_i $$
怎样选择才能使整体的贡献最大。
分析
很精妙的贪心。先假设选择的花的集合 $S \subset \mathbb{N}_{\leqslant n}$,每种先选 $1$ 朵,接下来考虑剩下的数量如何分配。必然的,应该全部分配给 $S$ 中最大的 $b_i$。
换种角度考虑,答案可能是全部只选了 $1$ 朵,或者必然只有一种多于 $1$ 朵。我们可以考虑枚举第 $i$ 朵花多于 $1$ 朵。
再注意到,当第 $j$ 种花满足 $a_j > b_i$ 时,应该选择一朵 $a_j$。
全部的 $a_j > b_i$ 可以通过二分 + 前缀和得到,需注意分类讨论前缀和是否包含了 $a_i$。
void solve() {
int n, m;
cin >> n >> m;
vector<pii> v(m + 1);
for (int i = 1; i <= m; i++) {
cin >> v[i].x >> v[i].y;
}
sort(v.begin() + 1, v.end());
vector<ll> sum(m + 1);
for (int i = 1; i <= m; i++) {
sum[i] = sum[i - 1] + v[i].x;
}
ll ans = 0;
for (int i = 1; i <= m; i++) {
int pos = upper(1, m, [&](int M) {
return v[M].x > v[i].y;
});
int num = m - pos + 1;
if (num <= n) {
ll tans = sum[m] - sum[pos - 1] + (n - num) * v[i].y;
if (pos > i) {
tans += v[i].x - v[i].y;
}
ans = max(ans, tans);
} else {
ans = max(ans, sum[m] - sum[max(0, m - n)]);
}
}
cout << ans << "\n";
}
全部代码请看:Codeforces/CF1379/CF1379C.cpp。