一、打怪
题目描述
我们需要击败一系列毛球怪。我方属性为血量 h 和攻击 a,怪物属性为血量 H 和攻击 A。
战斗规则如下:
- 双方轮流攻击,我方先手。
- 当血量小于等于 0 时死亡。
- 目标是在存活的前提下,计算最多能击杀多少只怪物。
- 若可无限击杀,输出
-1。
解题思路
面对这类问题,直观的想法是模拟战斗过程并计数。但考虑到数据规模,直接模拟可能导致超时,尤其是当怪物数量无限时。
既然单只怪物的属性固定,我们可以推导单次击杀所需的代价。
- 计算击杀次数:要杀死一只血量为
H、攻击力为a的怪物,需要攻击次数m = H/a + (H%a == 0 ? 0 : 1)。 - 计算承受伤害:由于我方先手,在成功击杀前,我方只会受到
m-1次反击。因此单次击杀承受伤害r = (m - 1) * A。 - 计算总击杀数:基于我方总血量
h和单次代价r,可推算最大击杀数。需注意边界条件:如果h % r == 0,说明在第h/r只怪物时生命值会归零,实际只能杀h/r - 1只;否则为h/r。 - 特殊情况:若我方一次攻击即可秒杀 (
a >= H),则无伤通关,结果为-1。
参考实现
#include <iostream>
using namespace std;
int h, a, H, A;
int solve() {
if (H <= a) return -1;
int m = H / a + (H % a == 0 ? 0 : 1); // 几次攻击能杀死一只怪
int n = m - 1; // 杀死一只怪要受到几次怪物的攻击
int r = n * A; // 杀死一只怪要受到的伤害
int ret = (h % r == 0) ? (h / r - 1) : (h / r);
ret;
}
{
t;
cin >> t;
(t--) {
cin >> h >> a >> H >> A;
cout << () << endl;
}
;
}


