题目

小爱和小艾两人组队打一只怪兽。一开始怪兽有 \(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\)

算法分析

  1. 把每分钟分成 \(a \times b\) 份,这样是为了让他们攻击的点都在整数上
    那么小爱攻击 \(a\) 下,则攻击间隔是 \(b\) 时间
    小艾攻击 \(b\) 下,则攻击间隔是 \(a\) 时间

暴击的性质:一定是 \(a\) 的倍数,也一定是 \(b\) 的倍数,公倍数
公倍数为最小公倍数的倍数

所以暴击点就是 \(\operatorname{lcm}(a, b)\) 的倍数

  1. \(\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;
}