Codeforces 2023/2024 A-H
题面
难度:红 橙 黄 绿 蓝 紫 黑 黑
题解
A
题目大意:
输入
, ,解不等式 ,输出 。
解题思路:移项,得
#include <bits/stdc++.h> using namespace std; int t, a, b; int main() { scanf("%d", &t); while (t--) { scanf("%d%d", &a, &b); if (a >= b) printf("%d\n", a); else { int x = b - a; if (x <= a) printf("%d\n", a - x); else printf("0\n"); } } return 0; }
B
洛谷上这道题的题意翻译是我写的。
题目大意:
本题有多组测试数据。
有一台柠檬水自动售货机。机器上有个槽位和 个按钮,每个槽位对应一个按钮,但你并不知道每个按钮对应的是哪个槽位。
当您按下第个按钮时,有两种可能的事件:
- 若
号槽位有至少一瓶柠檬水,则其中一瓶柠檬水会从这个槽位里掉下来,然后你会把它取走。 - 若
号槽位没有柠檬水,则什么都不会发生。 柠檬水下落速度很快,因此您看不清它从哪个槽位掉出。您只知道每个槽位中瓶装柠檬水的数量
您需要求出至少收到瓶柠檬水的最小按按钮次数。
数据保证机器中至少存在瓶柠檬水。
题目分析:
贪心+排序。
定义“按钮按空”表示:该按钮按下若干次后,不再掉下柠檬水(即对应槽位中没有柠檬水)。
设当前有柠檬水的槽位中,数量最少的槽位为
因此考虑进行如下操作:找到所有有柠檬水的槽位中,数量最少的槽位的柠檬水数,设为
解题思路:
可以考虑从小到大对数组
总时间复杂度
注:写下这篇题解时,作者想要复习一下堆的用法。
#include <bits/stdc++.h> using namespace std; long long n, k, a[200010]; priority_queue<long long, vector<long long>, greater<long long> > q; int main() { long long t; scanf("%lld", &t); while (t--) { while (!q.empty()) q.pop(); scanf("%lld%lld", &n, &k); for (long long i = 1; i <= n; i++) { scanf("%lld", &a[i]); q.push(a[i]); } long long tmpn = n, cnt = 0; long long ans = 0; while (true) { if ((q.top() - cnt) * tmpn >= k) { ans += k; break; } ans += (q.top() - cnt) * tmpn + 1; k -= (q.top() - cnt) * tmpn; tmpn--; cnt = q.top(); q.pop(); } printf("%lld\n", ans); } return 0; }
C
题目大意:
有
个二元组 。需要将二元组拼接形成一个序列,使序列中的逆序对个数最少。求这个序列。
题目分析:
不难想到贪心。观察可以发现对于二元组
#include <bits/stdc++.h> using namespace std; struct akioi { int a, b; } dat[100010]; int n, t; bool cmp(akioi a, akioi b) { return a.a + a.b < b.a + b.b; } int main() { scanf("%d", &t); while (t--) { scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d%d", &dat[i].a, &dat[i].b); } sort(dat + 1, dat + n + 1, cmp); for (int i = 1; i <= n; i++) { printf("%d %d ", dat[i].a, dat[i].b); } } return 0; }
D
题目大意:
Prokhor 想要参加 IOI 3024。比赛共有
道题,参赛者会先看到第 题。比赛规则和现行规则有区别。
当他看到第题时有两种可能的操作:
- A 了这道题,并获得
分; - 放弃这道题。
不论执行哪种操作,第
题都被标记“已访问”。
接着,他会看到编号为的问题。对于两种操作:
- 若 A 了第
题,则有条件 ; - 若放弃第
题,则有条件 。 无论如何,第
题应“未被访问过”。此时取满足条件 的最大值。
当不存在合法的时候比赛结束。显然,如果他 A 了第 题,则比赛立即终止。
Prokhor 很 FAKE,所以他能 AK IOI。你需要帮他确定一种做题方案使得他获得全场最高分。
题目分析:
注意到到达第
答案为
#pragma GCC optimize(3) #include <bits/stdc++.h> using namespace std; #define int long long struct Edge { int y, w; }; struct Node { int y, d; bool operator < (const Node &n1) const { return d > n1.d; } }; const int inf = 0x3f3f3f3f; const int N = 400005; int n, d[N], a[N], b[N]; vector<Edge> g[N]; bool vis[N]; void dijkstra(int v0) { priority_queue<Node> q; for (int i = 1; i <= n; i++) { vis[i] = false; d[i] = 0x7f7f7f7f7f7f7f7f; } d[v0] = 0; q.push((Node) { v0, 0 }); while (!q.empty()) { Node n1 = q.top(); q.pop(); int x = n1.y; if (vis[x]) continue; vis[x] = true; for (int j = 0; j < g[x].size(); j++) { Edge next = g[x][j]; int y = next.y, w = next.w; if (vis[y]) continue; if (d[x] + w < d[y]) { d[y] = d[x] + w; q.push((Node) { y, d[y] }); } } } } char buf[1 << 20], *p1, *p2; inline char gc() { return p1 == p2 ? p2 = buf + fread(p1 = buf, 1, 1<<20, stdin), (p1 == p2) ? EOF : *p1++ : *p1++; } inline int read() { char c = gc(); int x = 0; while (c < '0' || c > '9') c = gc(); while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = gc(); return x; } inline void write(int x) { if (x > 9) write(x / 10); putchar(x % 10 ^ 48); } signed main() { int t = read(); while (t--) { n = read(); g[1].clear(); for (int i = 2; i <= n; i++) { g[i].clear(); g[i].push_back({i - 1, 0}); } for (int i = 1; i <= n; i++) { a[i] = read(); } for (int i = 1; i <= n; i++) { b[i] = read(); g[i].push_back({b[i], a[i]}); a[i] += a[i - 1]; // qian zhui he } dijkstra(1); int ans = 0; for (int i = 1; i <= n; i++) { ans = max(ans, a[i] - d[i]); } write(ans); putchar('\n'); } return 0; }
E
题目大意:
在两个强连通图中连接
条有向边,使得:
- 每个环的长度为
的倍数; - 所有“入点”恰好多一条入边;
- 所有“出点”恰好多一条出边;
- 每条边从其中一个强连通图出发,指向另一个强连通图。
题目分析:
还是看这个吧,这是官方题解。下面是文章翻译:
考虑一个强连通图,其中所有环的长度都是
的倍数。注意到,总是可以用 种颜色给这个图上色,使得任何一条边都可以将一个颜色为 的顶点连接到一个颜色为 的顶点。不难发现,只有当这些边保持所描述的颜色不变时,我们才能向图中添加边。 让我们给原图上一些颜色。使用固定的颜色,很容易检查是否可以添加所需的边。为此,我们将为每种颜色和每种顶点创建相应的
数组,然后我们将根据上面提到的标准比较数组的元素。然而,我们最初可以用不同的方式给第二个图上色,例如,通过在每个顶点的颜色上加上 对 取模。不难验证第二个图的计数数组的所有值在一个周期内都会移动 。同样,根据颜色的不同,所有的值都可以循环地任意移动。为了解决这个问题,我们将以这样一种方式构造初始数组,对于固定的着色,需要检查它们是否相等。如果对某些着色实现了相等,则意味着一个数组是另一个数组的循环移位。可以使用 KMP 算法检查这种情况。
本文来自博客园,作者:cwkapn,转载请注明原文链接:https://www.cnblogs.com/chenaknoip/p/18514838
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)