1 条题解
-
0
自动搬运
来自洛谷,原作者为

一扶苏一
休息结束。邮箱 yifusuyi@qq.com搬运于
2025-08-24 21:14:38,当前版本为作者最后更新于2018-05-20 19:49:21,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
[语言月赛202303] Coin Selection G 题解
Source & Knowledge
2023 年 3 月语言月赛,由洛谷网校入门计划/基础计划提供。
本题考察循环结构。
文字题解
题目大意
小 F 和小 B 玩游戏。初始时,他们有 元钱。桌子上有 枚硬币,第 枚硬币的价值是 元。
双方交替操作,每次双方在桌面上剩余的硬币中,选择不超过手中钱数的硬币里价值最高的那个硬币,拿到手里。
如果没有硬币不超过手里的钱数,则选择价值最低的硬币。求游戏结束时双方手里的钱数。
,。
解析
依题意模拟。
注意到一共会进行 次操作,可以用一个长度为 的循环依次来进行每次取硬币。每次一个硬币被拿走后,可以把它对应的 改为 ,标记为它已经被拿走了。
可以发现,当 是奇数时,小 F 操作,否则小 B 操作。于是可以通过 的奇偶性判断当前的操作的玩家。
for (int i = 1; i <= n; ++i) { if (i % 2 == 1) { // 小 F 操作 } else { // 小 B 操作 } }接下来,以小 F 操作为例,介绍如何找到当前选择的硬币。
首先用一个全局变量 维护小 F 当前手里的钱数。然后扫描一遍数组,维护一个变量 ,它的含义是在已扫描的元素里不大于 的那些硬币里价值最大的的硬币的所在下标。可以用类似打擂台的形式求出 :
int pos = 0; for (int j = 1; j <= n; ++j) if (a[j] <= sa) { if (a[pos] < a[j]) pos = j; }注意到如果如果所有硬币都比 大,那么上面的循环结束后 仍然为 。此时我们需要在剩余硬币中找到那个不为 且最小的:
if (pos == 0) { for (int j = 1; j <= n; ++j) if (a[pos] == 0) { pos = j; } else if (a[j] > 0 && a[pos] > a[j]) pos = j; }至此,我们就找到了这次所拿的硬币的下标 。只需要给 加上 再把 置零即可:
sa += a[pos]; a[pos] = 0;类似的,可以完成小 F 对应的操作代码,把二者填充到上面的 for 循环中,就完成了题目的主体。
观察数据范围:,显然 应该用
long long来存。那么 呢?注意到每个人至多拿 (向上取整)个硬币,也就是最多拿 枚硬币,所以 不超过 。而long long的上界是 ,所以 也可以用long long存下。视频题解
完整代码请在视频中观看。
- 1
信息
- ID
- 8479
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 1
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者