Codeforces Round 972 (Div. 2)

A. Simple Palindrome

大致题意

只允许使用 aeiou 构建一个字符串,使得其中的回文子序列尽可能少

思路

注意是回文子序列,所以比如 aeioua 这种,看起来一个回文串都没有,实际上 aea, aia, aoa 等等都是可以构造出来的

显然,如果存在间隔的方式,那么带来的回文串一定会更多,毕竟 aea 里面还可以再提取出一个 aa。所以应该保证尽可能不要出现间隔字母即可,同时联系的字母也要少

AC code

1
2
3
4
5
6
7
8
void solve() {
int n;
cin >> n;
int cnt[5] = {0, 0, 0, 0, 0};
for (int i = 0; i < n; ++i) ++cnt[i % 5];
for (int i = 0; i < 5; ++i) for (int j = 0; j < cnt[i]; ++j) cout << "aiueo"[i];
cout << endl;
}

B2. The Strict Teacher

大致题意

有一排方格,其中一部分格子上有老师,老师希望抓住某个学生,且老师和学生每次都会停留在当前的格子或者走到相邻的格子,给出老师的初始位置,询问如果学生的初始位置在某个值时,需要多久才能抓到

思路

只需要考虑在所有老师最左边或者在最右边,或者在某两个中间这三种情况即可,简单题

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void solve() {
int n, m, q;
cin >> n >> m >> q;
vector<int> data(m);
for (auto &item: data) cin >> item;
sort(data.begin(), data.end());
while (q--) {
int t;
cin >> t;
if (t < data[0]) cout << data[0] - 1 << endl;
else if (t > data.back()) cout << n - data.back() << endl;
else {
auto iter = upper_bound(data.begin(), data.end(), t);
int r = iter.operator*();
--iter;
int l = iter.operator*();
cout << (r - l) / 2 << endl;
}
}
}

C. Lazy Narek

大致题意

有 $n$ 个字符串,每个字符串长度为 $m$,允许选择其中几个(或者一个都不选),并按照原来的顺序拼接起来,
然后再从拼接后的字符串提取出一个子序列,使得这个子序列恰好是多个连续的 narek 这个字符串
将此子序列的长度减去提取走子序列后的 narek 字母数量,得到分数,问分数最大是多少

思路

对于每一个字符串,当需要使用这个字符串的时候,当前状态只有 5 种可能的开始,即当前需要匹配 n/a/r/e/k 的时候,同时也只有 5 种结束状态

所以只需要枚举每一个字符串在不同的字母结束的时候的最优分数,然后做一下动态规划即可

AC code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void solve() {
signed _;
cin >> _;
for (signed tc = 0; tc < _; ++tc) {
int n, m;
cin >> n >> m;
string str = "narek";
vector<string> data(n);
for (auto &item: data) item.reserve(m);
for (auto &item: data) cin >> item;
vector<vector<int>> dp(n);
for (int i = 0; i < n; ++i) {
dp[i].resize(5, -1000000);
for (int k = 0; k < 5; ++k) {
int cur = k, soc = 0;
for (auto &c: data[i]) {
if (c == str[cur]) {
++cur;
if (cur == 5) {
soc += 5;
cur = 0;
}
} else if (c == 'n' || c == 'a' || c == 'r' || c == 'e' || c == 'k') --soc;
}
if (k == 0) dp[i][cur] = max(dp[i][cur], soc);
if (i > 0) {
dp[i][k] = max(dp[i - 1][k], dp[i][k]);
dp[i][cur] = max(dp[i - 1][k] + soc, dp[i][cur]);
}
}
}
int ans = 0;
for (int j = 0; j < n; ++j) for (int i = 0; i < 5; ++i) ans = max(ans, dp[j][i] - i);
cout << ans << endl;
}
}

Codeforces Round 972 (Div. 2)
https://blog.mauve.icu/2024/09/16/acm/codeforces/CodeforcesRound972/
作者
Shiroha
发布于
2024年9月16日
许可协议