AtCoder Beginner Contest 236 题解
作者:@cherish.
课程学习内容为作者从学校的PPT处摘抄,仅供自己学习参考,若需转载请注明出处:https://www.cnblogs.com/cherish-/p/15843386.html
AtCoder Beginner Contest 236
目前补到F
A - chukodai
题目描述:给你一个字符串,下标从1
开始,再给你两个整数a , b
,将字符串中位置a
和位置b
的字符交换位置并输出交换后的字符串。
思路:根据题意模拟即可
时间复杂度:
参考代码:
void solve() {
string s;
cin >> s;
int a, b;
cin >> a >> b;
swap(s[a - 1], s[b - 1]);
cout << s << '\n';
}
B - Who is missing?
题目描述:给你张卡片,每张卡片上有一个之间的数字,同一数字最多出现4
次,有一个数字只出现了三次,请将这个数字找出来。
思路:根据题意模拟即可
时间复杂度:
参考代码:
void solve() {
int n;
cin >> n;
vector<int>cnt(n + 1, 0);
int a;
for (int i = 1; i < 4 * n; ++i) cin >> a, cnt[a]++;
for (int i = 1; i <= n; ++i) {
if (cnt[i] == 3) {
cout << i << '\n';
return;
}
}
return;
}
C - Route Map
题目描述:给你两个集合,问的每个元素是否在中出现过,对于每个元素,若出现过输出Yes
,否则输出No
。
思路:使用set
或map
等数据结构存储中的元素,然后遍历中的元素在使用的数据结构中查找,根据查找结果输出相应的答案即可。
时间复杂度:
参考代码:
void solve() {
int n, m;
cin >> n >> m;
vector<string>strs(n);
for (int i = 0; i < n; ++i) cin >> strs[i];
map<string, bool>mp;
string s;
for (int i = 1; i <= m; ++i) {
cin >> s;
mp[s] = true;
}
for (auto s : strs) {
if (mp.count(s)) cout << "Yes" << '\n';
else cout << "No" << '\n';
}
return;
}
D - Dance
题目描述:有个人,让你将其分成组,每组中的两个人会有一个匹配值其中i , j
表示人的编号。问对于所有的分组方案,每一组的匹配值的异或和的最大值是多少。假设每组的匹配值为,即求的最大值。
数据范围:
思路:显然可以爆搜,因为要配对,如果当前已经枚举的人数为偶数,那么任选一个人作为下一组即可,若当前已经分配好的是奇数个,那么就要遍历剩下的人与前一个人组成一队。
时间复杂度:
参考代码:
void solve() {
int n;
cin >> n;
vector<vector<int>>a(2* n + 1, vector<int>(2 * n + 1, 0));
for (int i = 1; i <= 2 * n - 1; ++i) {
for (int j = i + 1; j <= 2 * n; ++j) cin >> a[i][j];
}
int res = 0, m = n << 1;
vector<bool>vis(2 * n + 1, false);
auto dfs = [&](auto dfs, int cur, int cnt, int ans) {
if (cnt == m) {
res = max(res, ans);
return;
}
if (cnt % 2 == 0) {
for (int i = 1; i <= m; ++i) {
if (vis[i] == true) continue;
vis[i] = true;
dfs(dfs, i, cnt + 1, ans);
vis[i] = false;
break;
}
}
else {
for (int i = cur + 1; i <= m; ++i) {
if (vis[i] == true) continue;
vis[i] = true;
int u = cur, v = i;
dfs(dfs, i, cnt + 1, ans ^ a[u][v]);
vis[i] = false;
}
}
};
vis[1] = true;
dfs(dfs, 1, 1, 0);
cout << res << '\n';
return;
}
E - Average and Median
题目描述:给你一个长度为的序列,你需要从中选出一些元素组成序列,选取规则为:,和至少有一个在序列中。求序列的均值的最大值和最大中位数。
数据范围:
思路:先考虑这样一个问题,若按照题目的选取规则,求选取的和最大。那么显然可以dp
,定义状态分别表示不选第个数和选第个数字,那么转移方程显然为:
因为只与前一项值有关,所以该递推式可以时间空间求解。
回到原问题:我们可以二分平均值的最大值mid
,那么将每一项a_i-mid
作为c_i
,那么原问题就等价于求按照上述选取规则使得序列的和大于等于0
。该过程可以使用上述方法求解。故求均值的最大值的复杂度为:。
再来看第二个问题,这是一个比较经典的问题,我们同样可以二分最大中位数,然后将序列数字小于的置为-1
,将数字大于等于的置为1
,那么原问题又转化为按照上述规则选取序列中的元素,使得最大和大于0
。该过程使用上述方法同样可以求解,总复杂度为。
时间复杂度:
空间复杂度:
参考代码:
template<class T>
T maximize(vector<T>& nums) {
T f = 0, g = 0;
for (auto& num : nums) {
T u = max(f, g) + num;
f = g;
g = u;
}
return max(f, g);
}
void solve() {
int n;
cin >> n;
vector<int>nums(n, 0);
for (auto& num : nums) cin >> num;
auto average = [&]()->void {
double lr = 1.0, rs = 1e9 + 5;
vector<double>b(n);
while ((rs - lr) / rs > 3e-7) {
double mid = sqrt(lr * rs);
for (int i = 0; i < n; ++i) b[i] = nums[i] - mid;
if (maximize(b) >= 0.0) lr = mid;
else rs = mid;
}
cout << fixed << setprecision(10) << lr << '\n';
return;
};
average();
auto median = [&]()->void {
int lr = 1, rs = 1e9 + 5;
vector<int>b(n);
while (lr + 1 < rs) {
int mid = lr + rs >> 1;
for (int i = 0; i < n; ++i) b[i] = nums[i] >= mid ? 1 : -1;
if (maximize(b) > 0) lr = mid;
else rs = mid;
}
cout << lr << '\n';
return;
};
median();
return;
}
F - Spices
题目描述:有个数字,获得一个数字需要花费,你的目的是在这些数字中选择一些数字组成集合,在集合中选择一些数字进行异或和可以得到之间的所有数字,求最小的花费。
思路:从求集合的角度来看,是一个比较裸的线性基,学习线性基的相关知识可以参考此处。要使花费最小,可以将数字和花费绑定并按照花费从小到大排序,然后正常求解即可。
时间复杂度:
参考代码:
void solve() {
int n, val;
cin >> n;
int m = 1 << n;
vector<pair<int, int>>a;
for (int i = 1; i < m; ++i) {
cin >> val;
a.push_back({ val , i });
}
std::sort(a.begin(), a.end());
vector<int>p(n + 1, 0);
long long res = 0;
for (int i = 1; i < m; ++i) {
int tmp = a[i - 1].second;
for (int j = n; j >= 0; --j) {
if (((tmp >> j) & 1) == 0) continue;
if (p[j] == 0) {
p[j] = tmp;
res += a[i - 1].first;
break;
}
else tmp ^= p[j];
}
}
cout << res << '\n';
return;
}
作者:cherish.
出处:https://home.cnblogs.com/u/cherish-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!