Problem F. Flower
问题描述
Yuki 面前有一朵含 n 片花瓣的花,她会进行多轮操作:每轮先摘 a 片花瓣,再摘 b 片花瓣(若剩余不足则摘完),直到花瓣全部摘完。她离开的条件是:最后一片花瓣是在某轮的前 a 片花瓣中被摘下的;否则她会留下。
我们可以提前摘一些花瓣(不能全摘),确保她留下。求最少需要提前摘的花瓣数量;若不可能,输出 “Sayonara”。
输入
第一行:整数
t(测试用例数)。每个测试用例:三个整数
n, a, b(花瓣总数、每轮先摘数量、每轮后摘数量)。1 ≤ t ≤ 1001 ≤ n ≤ 10⁹1 ≤ a, b ≤ 10⁹
输出
- 若能让 Yuki 留下,输出最少提前摘的花瓣数。
- 否则,输出 “Sayonara”。
题解
核心分析
Yuki 的每轮操作可视为 “先摘 a 片,再摘 b 片”,每轮最多摘 T = a + b 片(T 为单轮操作的最大花瓣数)。关键是判断最后一片花瓣的位置:
- 若最后一片在某轮的前
a片中 → Yuki 离开。 - 若最后一片在某轮的后
b片中 → Yuki 留下。
我们需要通过提前摘花瓣(设数量为 x),使剩余花瓣 m = n - x(m > 0)满足:最后一片花瓣在某轮的后 b 片中。
分情况
- 当
n ≤ a时: Yuki 第一轮就会摘完所有花瓣(因n ≤ a,最后一片在前a片中),她会离开。 若提前摘x片(x > 0,m = n - x > 0),则m < n ≤ a,同样最后一片在前a片中,无法让她留下。故输出 “Sayonara”。 - 当
n > a时: 计算n除以T的商k = n // T和余数r = n % T(即n = k*T + r,0 ≤ r < T):- 若
r = 0:刚好k轮摘完,最后一片在第k轮的后b片中 → 无需提前摘,x = 0。 - 若
r > a:最后一轮先摘a片,剩余r - a片(> 0),再摘b片(摘完r - a片),最后一片在后b片中 → 无需提前摘,x = 0。 - 若
0 < r ≤ a:最后一轮仅摘r片(前a片中),Yuki 会离开。需提前摘x = r片,剩余m = k*T(刚好k轮,最后一片在后b片中)→x = r。
- 若
代码
1 |
|
时间复杂度:O(t)
Problem D. Distant Control
问题描述
有 n 个机器人排成一行,初始状态为开(1)或关(0)。你可以执行两种操作:
- 选择
a个连续且全为开的机器人,将它们全关掉。 - 选择
a+1个连续且全为关的机器人,将它们全打开。
目标是通过若干次操作(可零次),使最终开着的机器人数量最大化。
输入
第一行:整数
t(测试用例数)。每个测试用例:
- 第一行:整数
n(机器人数量)和a(操作参数)。 - 第二行:长度为
n的字符串s,表示初始状态(0 为关,1 为开)。
- 第一行:整数
1 ≤ t ≤ 4×10⁴2 ≤ n ≤ 2×10⁵1 ≤ a ≤ n-1所有测试用例的
n之和 ≤4×10⁵
输出
每个测试用例输出最大可能的开着的机器人数量。
题解
两种操作的影响:
- 操作 1(关):减少
a个开着的机器人(代价)。 - 操作 2(开):增加
a+1个开着的机器人(收益)。
由于 a+1 > a,操作 2 的收益大于操作 1 的代价,因此策略核心是最大化操作 2 的次数,同时考虑是否通过操作 1 创造更多操作 2 的机会。
- 连续片段分解:将初始状态分解为连续的 “0 片段”(关)和 “1 片段”(开)。例如 “001” 分解为 (0,2)、(1,1)(类型,长度)。
- 基础收益:对每个 0 片段(长度
z),最多可执行z // t次操作 2(t = a+1),每次增加t个开着的机器人,总收益为(z // t) * t。 - 合并收益:相邻两个 0 片段之间夹着一个 1 片段(长度
b)时:- 若
b ≥ a(可执行操作 1 关掉该 1 片段),则两个 0 片段合并为长度z1 + z2 + b(原 1 片段变为 0)。 - 合并后可能增加操作 2 的次数,额外收益为:
(合并后0片段的操作2收益) - (原两个0片段的操作2收益) - b(关掉 1 片段损失的数量)。 - 若额外收益为正,则值得合并。
- 若
思路
- 分解初始状态为连续片段,计算初始开着的机器人数量
ini。 - 计算所有 0 片段的基础操作 2 收益
base。 - 计算所有可能合并相邻 0 片段的额外收益,取最大值
max_merge(若为正则加入总收益)。 - 最终结果为
ini + base + max(max_merge, 0)。
代码
1 |
|
时间复杂度:O(t * n)
Problem J. Jetton
问题描述
Yuki 和 Ena 玩回合制扑克牌游戏:
- 初始时,Yuki 有
x筹码,Ena 有y筹码。 - 每轮胜负规则:
- 若筹码数不同,筹码少的玩家获胜。
- 若筹码数相同,Yuki 获胜。
- 输家需支付给赢家与赢家当前筹码数相等的金额。
- 当任一玩家筹码数为 0 时,游戏结束。
求游戏是否会在有限轮内结束,若是则输出轮数,否则输出 -1。
输入
- 第一行:整数
t(测试用例数)。 - 后续
t行:每行两个整数x和y(初始筹码数)。
约束
1 ≤ t ≤ 10⁵1 ≤ x, y ≤ 10⁹
输出
- 若游戏在有限轮内结束,输出轮数。
- 否则,输出
-1。
题解
- 游戏规则转化:
- 若
x ≠ y,设m = min(x, y),则下一轮筹码变为(x + m, y - m)或(x - m, y + m)。 - 若
x = y,则 Yuki 获胜,Ena 支付x,游戏结束(1 轮)。
- 若
- 终止条件:
- 每轮后总筹码
S = x + y保持不变。 - 若
S为奇数,游戏无法结束(因无法通过操作使任一筹码为 0)。 - 若
S为偶数,需进一步分析是否能通过有限次操作使某玩家筹码为 0。
- 每轮后总筹码
二进制分解:
总筹码
S的二进制中最低位 1 的位置k(即S能被2^k整除但不能被2^(k+1)整除)。初始时较小的筹码
1
u = min(x, y)
必须满足:
u是S / 2^k的倍数。u的二进制中最低位 1 的位置r ≤ k-1。
轮数计算:
- 若满足上述条件,轮数为
k - r,即S和u的最低位 1 位置之差。
实现方法
- 特殊情况处理:
- 若
x == y,直接输出 1 轮。 - 若
S = x + y为奇数,输出-1。
- 若
- **计算
k和r**:k:S的二进制中最低位 1 的位置。r:u = min(x, y)的二进制中最低位 1 的位置。
- 验证条件:
- 检查
u是否为S / 2^k的倍数。 - 检查
r ≤ k-1。
- 检查
- 输出结果:
- 若条件满足,输出
k - r。 - 否则,输出
-1。
- 若条件满足,输出
代码
1 |
|
时间复杂度:O(t)