Hello 2023 A-D
A
题意
给一个字符串每个物品对应的灯的照明方向,L/R
能照亮它左侧/右侧的所有物品(不包括自己对应的物品),现在能交换相邻两个灯一次(不改变照明方向),问能否找亮所有物品。
题解
知识点:贪心。
显然,如果存在 LR
或 RL
就可以照亮全部,否则全是 L
或 R
就不可行。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; bool solve() { int n; cin >> n; string s; cin >> s; s = "?" + s; for (int i = 1;i < n;i++) { if (s[i] != s[i + 1]) { if (s[i] == 'L') cout << i << '\n'; else cout << 0 << '\n'; return true; } } return false; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
B
题意
构造一组数,使得任意相邻两项之和等于全部和。
题解
知识点:构造。
为偶数时,构造 即可。
为奇数时,显然奇数项和偶数项要各自相等,随后由 可以得到 ,取 即可,只有 时无解(因为 )。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; bool solve() { int n; cin >> n; if (n & 1) { if (n == 3) return false; cout << "YES" << '\n'; for (int i = 1;i <= n;i++) { if (i & 1) cout << n - 3 << ' '; else cout << 1 - n << ' '; } cout << '\n'; } else { cout << "YES" << '\n'; for (int i = 1;i <= n;i++) { if (i & 1) cout << 1 << ' '; else cout << -1 << ' '; } cout << '\n'; } return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << "NO" << '\n'; } return 0; }
C
题意
给一组数,可以修改元素变成其相反数。问最少修改几次,可以使得第 个前缀和 是所有前缀和里最小的。
题解
知识点:枚举,前缀和,数学,贪心。
定义 。
当 时
当 时
所以只要保证任意 ,满足 ;任意 ,满足 即可。
每次操作时,贪心地取最优的即可。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int a[200007]; bool solve() { int n, m; cin >> n >> m; for (int i = 1;i <= n;i++) cin >> a[i]; int cnt = 0; multiset<int> ms; ll sum = 0; for (int i = m;i >= 2;i--) { sum += a[i]; ms.insert(a[i]); if (sum > 0) { sum -= 2 * (*prev(ms.end())); ms.erase(prev(ms.end())); cnt++; } } ms.clear(); sum = 0; for (int i = m + 1;i <= n;i++) { sum += a[i]; ms.insert(a[i]); if (sum < 0) { sum -= 2 * (*ms.begin()); ms.erase(ms.begin()); cnt++; } } cout << cnt << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << -1 << '\n'; } return 0; }
D
题意
给定一组头发长度 ,以及理想头发长度 。
理发师有刀片 ,每个刀片只能用一次,每次可以修减一段连续区间的头发,满足 。
问理发师能不能通过这些刀片将 修剪至 。
题解
知识点:单调栈。
显然 无解。
利用最大值单调栈维护刀片的值。以下按顺序满足:
- 大于栈顶刀片,则栈顶刀片因为太小不能再用了,刀片需要出栈直至 小于等于栈顶刀片或栈空。
- ,说明 不需要修剪,什么都不用干。
- ,说明 需要修剪,此时如果 小于栈顶刀片或栈空,则需要使用新的刀片,满足 ,如果不存在这个刀片则无解。
全部满足后,即 YES
。
时间复杂度
空间复杂度
代码
#include <bits/stdc++.h> #define ll long long using namespace std; int a[200007]; int b[200007]; bool solve() { int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i]; for (int i = 1;i <= n;i++) cin >> b[i]; int m; cin >> m; map<int, int> mp; for (int i = 1;i <= m;i++) { int x; cin >> x; mp[x]++; } stack<int> st; for (int i = 1;i <= n;i++) { if (a[i] < b[i]) return false; while (!st.empty() && b[i] > st.top()) st.pop(); if (a[i] != b[i]) { if (st.empty() || b[i] < st.top()) { if (mp[b[i]]) { mp[b[i]]--; st.push(b[i]); } else return false; } } } cout << "YES" << '\n'; return true; } int main() { std::ios::sync_with_stdio(0), cin.tie(0), cout.tie(0); int t = 1; cin >> t; while (t--) { if (!solve()) cout << "NO" << '\n'; } return 0; }
本文来自博客园,作者:空白菌,转载请注明原文链接:https://www.cnblogs.com/BlankYang/p/17024753.html
分类:
CF
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧