Codeforces Round 972 (Div. 2)
A
如果有两个相同的字符,中间隔了若干个字符,形如 A******A
,那么会产生很多回文子序列。
为了避免这种情况,考虑将相同字符放在相邻位置,于是得到本题的正解构造:
首先将长度尽可能平分到 5 组,每组用相同字符重复 次或 次。
#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
#define IOS
#define MULTI
char mp[] = { 'a', 'e', 'i', 'o', 'u' };
void solve() {
int n;
cin >> n;
int m = n % 5, t = n / 5;
for (int i = 0; i < m; ++i)
for (int j = 0; j <= t; ++j)
cout << mp[i];
for (int i = m; i < 5; ++i)
for (int j = 0; j < t; ++j)
cout << mp[i];
cout << '\n';
}
int main() {
#ifdef IOS
ios::sync_with_stdio(false);
cin.tie(nullptr);
#endif
#ifdef MULTI
int TestCase = 1;
for (cin >> TestCase; TestCase--;) solve();
#else
solve();
#endif
return 0;
}
B
- David 被两个老师夹住:
那么答案非常显然,假设两个老师之间有 个空位,David 只能活 轮。
这个可以排序后用lower_bound
找到 David 左右的老师。 - David 没有被老师夹住:
那么 Daivd 显然会贪心地往边界跑,那么只需要求出离他最近的老师 的位置,答案就是 或者 。
#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
#define IOS
#define MULTI
void solve() {
int n, m, q;
cin >> n >> m >> q;
vector<int> b(m);
for (int &x : b)
cin >> x;
sort(begin(b), end(b));
for (; q--;) {
int x;
cin >> x;
if (x < b[0]) {
cout << b[0] - 1 << '\n';
} else if (x > b.back()) {
cout << n - b.back() << '\n';
} else {
int p = upper_bound(begin(b), end(b), x) - begin(b);
int y = b[p] - b[p - 1] - 1;
cout << (y + 1) / 2 << '\n';
}
}
}
int main() {
#ifdef IOS
ios::sync_with_stdio(false);
cin.tie(nullptr);
#endif
#ifdef MULTI
int TestCase = 1;
for (cin >> TestCase; TestCase--;) solve();
#else
solve();
#endif
return 0;
}
C
给人一种显然 dp 的感觉。用 dp[i][j]
表示前 个字符串种选了若干个字符串,选完后 Narek 贪心匹配到了第 个字符,此时的得分最大值。
那么只需要对每个字符串求出,假设之前已经匹配了 个字符,经过这个字符串后,贪心匹配到了哪个字符(),完美匹配了几次()。用二元组 记录即可转移。
#include <bits/stdc++.h>
using namespace std;
using u32 = unsigned;
using i64 = long long;
using u64 = unsigned long long;
using i128 = __int128;
#define IOS
#define MULTI
template<typename T>
void chmax(T &x, T y) {
if (y > x)
x = y;
}
int mp[256];
void solve() {
int n, m;
cin >> n >> m;
vector<string> s(n);
vector<int> cnt(n);
vector<array<pair<int, int>, 5>> g(n);
for (int i = 0; i < n; ++i) {
cin >> s[i];
array<pair<int, int>, 5> res;
for (int j = 0; j < 5; ++j)
res[j] = { 0, j };
for (char ch : s[i]) {
cnt[i] += !!mp[ch];
for (int j = 0; j < 5; ++j) {
auto &[ans, cur] = res[j];
if (cur + 1 == mp[ch])
++cur;
if (cur == 5)
cur = 0, ans += 5;
}
}
g[i] = res;
// cout << "string " << i << "\n";
// for (int j = 0; j < 5; ++j) {
// auto [a, c] = res[j];
// cout << a << " " << c << '\n';
// }
}
vector<array<int, 5>> f(n + 1);
// f[i][j]: first i strings, matched to ch j, max
for (int i = 0; i <= n; ++i)
for (int j = 0; j < 5; ++j)
f[i][j] = -1e9;
f[0][0] = 0;
for (int i = 0; i < n; ++i) {
for (int j = 0; j < 5; ++j) {
// cout << "f[" << i << "][" << j << "] = " << f[i][j] << '\n';
auto [ans, cur] = g[i][j];
chmax(f[i + 1][cur], f[i][j] + 2 * ans - cnt[i]);
chmax(f[i + 1][j], f[i][j]);
}
}
int ans = 0;
for (int i = 0; i < 5; ++i)
chmax(ans, f[n][i]);
cout << ans << '\n';
}
int main() {
mp['n'] = 1;
mp['a'] = 2;
mp['r'] = 3;
mp['e'] = 4;
mp['k'] = 5;
#ifdef IOS
ios::sync_with_stdio(false);
cin.tie(nullptr);
#endif
#ifdef MULTI
int TestCase = 1;
for (cin >> TestCase; TestCase--;) solve();
#else
solve();
#endif
return 0;
}
D
因为本题原做法的时间复杂度有问题,无法通过本题,暂时删去这部分内容。
E
没看。
本文来自博客园,作者:lingfunny,转载请注明原文链接:https://www.cnblogs.com/lingfunny/p/18414901
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效