[传智杯#2 决赛]

​[传智杯#2 决赛] 补刀

题目描述

UIM 在写程序的空闲玩一款 MOBA 游戏。
在这里插入图片描述

当敌方的小兵进入到我方防御塔的范围内,就会持续受到防御塔造成的伤害;当然我方英雄也可以对它造成伤害。当小兵的血量降到了 0
或者更低,就会被击杀。为了获得经验,UIM 希望在防御塔将这个小兵杀死之前,亲自补刀将其击杀。

为了简化问题,我们假设这个小兵有 ℎh 点的生命值。每次防御塔的攻击可以给小兵造成 x 点伤害,而你的英雄每次攻击可以给小兵造成 y
点伤害。你的攻击速度和防御塔攻击速度相同,所以你可以在防御塔第一次攻击小兵之前,或者每次防御塔攻击之后,选择是否对小兵进行一次攻击,当然你也可以选择不攻击。

现在想知道,给出这些信息,判断英雄是否有办法将这个小兵击杀?

输入格式

每个测试点由多组数据组成。

输入第一行,包含一个正整数 T,表示数据组数。

接下来 T 行,每行三个非负整数 h,x,y,其意义已经在题目描述中给出。

输出格式

输出 T 行。对于每组数据,如果可以最后将小兵击杀,输出 Yes,否则输出 No。

输入输出样例

输入

5 
100 100 1 
100 97 1 
100 98 1 
100 99 1 
100 100 0 

输出

No
No 
Yes 
Yes 
No

说明/提示

数据的组数不多于 50,1≤ℎ≤1018,0≤x,y≤1018

解题思路

特殊情况

  1. 当英雄攻击力y==0时,无法击杀小兵,输出No
  2. 在第一种条件不成立情况下,当英雄攻击力y>=h时,则英雄可以选择在防御塔第一次攻击前攻击小兵,进行首击击杀。
  3. 在前两种条件不成立条件下,也就是英雄攻击力不为0且无法第一次就击杀小兵。开始判断防御塔攻击力。当防御塔攻击力x==0时,不存在小兵被防御塔击杀,直接输出Yes
  4. 在前三种条件都不成立条件下,也就是英雄和防御塔攻击力都不为0,且英雄无法首击击杀小兵。当防御塔攻击力x>=h时,只会出现 防御塔攻击;英雄攻击,防御塔攻击 在两种情况,小兵就被击杀了。

代码如下:

if(y == 0) No
if(y >= h) Yes 
if(x == 0) Yes
if(x >= h) No

最后的情况

  1. 让防御塔主动攻击小兵,我们只要考虑判断英雄要不要出手达到击杀小兵的目的,防御塔每攻击一次,英雄则有一次可以选择攻击的机会,最后一次则必须由英雄攻击进行击杀。
  2. 因为英雄和防御塔攻击速度一样,计算防御塔最多攻击几下使得再攻击一下小兵就被击杀,cnt = h / x求出攻击次数。
  3. 判断 h%x == 0,被整除说明刚好可以被击杀,满足则cnt-1
  4. 得出防御塔攻击完后小兵剩余的血量 h_blood = h % x, if(h%x == 0),则h_blood = x
  5. 这里考虑的是最坏的情况,防御塔攻击的过程中英雄都有选择攻不攻击的权力,只要满足最后一次能将小兵击杀即可。
  6. 所以最坏情况下防御塔最多攻击cnt下,而英雄可以攻击cnt+1次(在防御塔第一次攻击之前攻击一次,以及防御塔每次攻击之后选择攻击一次,所以比防御塔多攻击一次)。
  7. 故用 (cnt+1)*y >= h_blood判断总攻击力能否达到剩余血量,如果可以则说明中间有<=cnt+1次可以选择攻击进行击杀;如果没达到剩余血量,因为攻击速度一样,所以下一次攻击一定是防御塔,则小兵一定会被防御塔击杀。

代码如下

LL cnt = h / x; //防御塔最多攻击的次数
LL h_blood = h % x; //小兵剩余血量
if(h_blood == 0) h_blood = x, cnt--; //刚好可以被击杀,少打一次,血量刚好为x
if((cnt+1) * y >= h_blood) Yes//英雄能造成总伤害比剩余血多,就能打死
else No

完整代码

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;

typedef long long LL;
#define No { cout << "No" << endl; continue; } 
#define Yes { cout << "Yes" << endl; continue; } 

int main(){ 
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n; cin >> n;
    while(n--){ 
        LL h, x, y; 
        cin >> h >> x >> y;
        if(y == 0) No
        if(y >= h) Yes
        if(x == 0) Yes
        if(x >= h) No
        
        LL cnt = h / x; //防御塔最多攻击的次数
        LL h_blood = h % x; //小兵剩余血量
        if(h_blood == 0) h_blood = x, cnt--; //刚好可以被击杀,少打一次,血量刚好为x
        if((cnt+1) * y >= h_blood) Yes //英雄能造成总伤害比剩余血多,就能打死
        else No

    } 
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coding酥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值