题目
小爱和小艾两人组队打一只怪兽。一开始怪兽有 \(n\) 点生命值,当 \(n\) 变成 \(0\) 或更低时,怪兽就被消灭了。他们两人是同时开始攻击的,小爱每分钟可以攻击 aa 下,小艾每分钟可以攻击 \(b\) 下。若 \(a=2\),\(b=4\),则小爱发出攻击的时刻为
\[0.5, ~1, ~1.5, ~2, ~2.5, ~\cdots
\]
小艾发出攻击的时刻为
\[0.25, ~0.5, ~0.75, ~1,~1.25, ~1.5, ~\cdots
\]
攻击分两种类型,普通攻击每次对怪兽造成 \(1\) 点伤害。若在某时刻,小爱和小艾恰好一同发出攻击,称为爆击
,爆击
将对怪兽造成成倍的伤害,共计 \((1+1)\times2=4\) 点伤害。
一旦攻击开始,就不会中断,直到怪兽被消灭为止,请问,对怪兽造成最后一点伤害的是哪一位玩家?如果最后一击是两人同时造成的,输出 C
(Combo的意思)。
输入格式
第一行:一个正整数表示 \(n\)。
第二行:两个正整数表示 \(a\) 与 \(b\)。
输出格式
- 若是小爱发出了最后一击,输出
A
; - 若是小艾发出了最后一击,输出
B
; - 若是两人的
爆击
为最后一击,输出C
。
限制:
- \(1 \leqslant n \leqslant 2 \times 10^7\)
- \(1 \leqslant a, b \leqslant 40000\)
算法分析
- 把每分钟分成 \(a \times b\) 份,这样是为了让他们攻击的点都在整数上
那么小爱攻击 \(a\) 下,则攻击间隔是 \(b\) 时间
小艾攻击 \(b\) 下,则攻击间隔是 \(a\) 时间
暴击的性质:一定是 \(a\) 的倍数,也一定是 \(b\) 的倍数,公倍数
公倍数为最小公倍数的倍数
所以暴击点就是 \(\operatorname{lcm}(a, b)\) 的倍数
- \(\operatorname{lcm}(a, b)\) 是一个循环,可以计算出攻击的伤害,用生命值 \(\%\) 伤害,最后看剩下的生命。
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, a, b;
cin >> n >> a >> b;
int l = lcm(a, b);
int dm = l/b + l/a + 2;
n %= dm;
if (n == 0 or n == dm-1 or n == dm-2 or n == dm-3) {
puts("C");
return 0;
}
int nowa = b; // a 第一次攻击在 b 时刻
int nowb = a; // b 第一次攻击在 a 时刻
for (int i = 1; i <= n; ++i) {
if (nowa < nowb) {
if (i == n) {
puts("A");
}
nowa += b;
}
else {
if (i == n) {
puts("B");
}
nowb += a;
}
}
return 0;
}