解题思路

  1. 模拟时间轴上的攻击事件:

    • 小兵攻击:每 时间一次,伤害为
    • 英雄普攻:每 时间一次,伤害为
    • 英雄技能:每 时间一次,伤害为
  2. 关键点:

    • 同时攻击时,小兵伤害先结算
    • 需要判断最后一击是否来自英雄
    • 英雄的普攻和技能可以同时使用

代码

#include <iostream>
using namespace std;

bool canGetReward() {
    int s, n, d, x, y, t0, t1, t2;
    cin >> s >> n >> d >> x >> y >> t0 >> t1 >> t2;
    
    // 模拟时间轴
    for(int time = 0; s > 0; time++) {
        // 计算当前时刻的伤害
        int damage = 0;
        
        // 小兵攻击(优先结算)
        if(time % t0 == 0) {
            damage += n * d;
        }
        
        // 如果当前伤害就能击杀防御塔,且不是英雄造成的,返回false
        if(damage >= s) {
            return false;
        }
        
        // 英雄攻击
        bool heroAttack = false;
        if(time % t1 == 0) {  // 普攻
            damage += y;
            heroAttack = true;
        }
        if(time % t2 == 0) {  // 技能
            damage += x;
            heroAttack = true;
        }
        
        // 更新防御塔血量
        s -= damage;
        
        // 如果防御塔被摧毁,检查是否是英雄造成的
        if(s <= 0 && heroAttack) {
            return true;
        }
    }
    return false;
}

int main() {
    int T;
    cin >> T;
    while(T--) {
        cout << (canGetReward() ? "YES" : "NO") << endl;
    }
    return 0;
}
import java.util.*;

public class Main {
    public static boolean canGetReward(Scanner sc) {
        int s = sc.nextInt();
        int n = sc.nextInt();
        int d = sc.nextInt();
        int x = sc.nextInt();
        int y = sc.nextInt();
        int t0 = sc.nextInt();
        int t1 = sc.nextInt();
        int t2 = sc.nextInt();
        
        // 模拟时间轴
        for(int time = 0; s > 0; time++) {
            // 计算当前时刻的伤害
            int damage = 0;
            
            // 小兵攻击(优先结算)
            if(time % t0 == 0) {
                damage += n * d;
            }
            
            // 如果当前伤害就能击杀防御塔,且不是英雄造成的,返回false
            if(damage >= s) {
                return false;
            }
            
            // 英雄攻击
            boolean heroAttack = false;
            if(time % t1 == 0) {  // 普攻
                damage += y;
                heroAttack = true;
            }
            if(time % t2 == 0) {  // 技能
                damage += x;
                heroAttack = true;
            }
            
            // 更新防御塔血量
            s -= damage;
            
            // 如果防御塔被摧毁,检查是否是英雄造成的
            if(s <= 0 && heroAttack) {
                return true;
            }
        }
        return false;
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();
        while(T-- > 0) {
            System.out.println(canGetReward(sc) ? "YES" : "NO");
        }
    }
}
def can_get_reward():
    s = int(input())
    n, d, x, y = map(int, input().split())
    t0, t1, t2 = map(int, input().split())
    
    # 模拟时间轴
    time = 0
    while s > 0:
        # 计算当前时刻的伤害
        damage = 0
        
        # 小兵攻击(优先结算)
        if time % t0 == 0:
            damage += n * d
        
        # 如果当前伤害就能击杀防御塔,且不是英雄造成的,返回False
        if damage >= s:
            return False
        
        # 英雄攻击
        hero_attack = False
        if time % t1 == 0:  # 普攻
            damage += y
            hero_attack = True
        if time % t2 == 0:  # 技能
            damage += x
            hero_attack = True
        
        # 更新防御塔血量
        s -= damage
        
        # 如果防御塔被摧毁,检查是否是英雄造成的
        if s <= 0 and hero_attack:
            return True
            
        time += 1
    return False

def main():
    T = int(input())
    for _ in range(T):
        print("YES" if can_get_reward() else "NO")

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:时间轴模拟
  • 时间复杂度:,其中 是防御塔的血量
  • 空间复杂度:,只需要常数额外空间