伟大的英雄
问题描述
伟大的Superhero守护着kkk掌管的国家。Superhero的攻击力为,初始健康值为,Superhero前面有个怪物,第个怪物的攻击力为,初始健康值为。第只怪物的攻击力为,初始健康值为。
如果Superhero或怪物的健康值为正数(大于或等于),则视作仍然活着;如果其健康值为非正数(小于或等于),则视作死亡。
为了保护国家的人民,Superhero会和怪物战斗,直到Superhero死了或者所有的怪物死了。
在每次战斗中,Superhero可以选择一个任意的活着的怪物,与之战斗。假设选择第iii只怪物,战斗前,Superhero和第iii只怪物的健康值分别为xxx和yyy。战斗结束后,Superhero和第iii只怪物的健康值分别变成x−aix-a_ix−ai和y−biy-b_iy−bi。
需要注意的是,Superhero可以多次打同一个怪物。
为了全国人民的安全,请告诉大家,Superhero是否能杀死所有的怪物(哪怕Superhero自己在杀死最后一个怪物后已经死了)。
输入格式
每个测试都包含多个测试用例。第一行包含ttt( 1≤t≤1051 \leq t \leq 10^51≤t≤105 )–测试用例的数量。测试用例的描述如下:
- 每个测试案例的第一行包含三个整数 AAA(1≤A≤1061 \leq A \leq 10^61≤A≤106)、BBB(1≤B≤1061 \leq B \leq 10^61≤B≤106)和nnn(1≤n≤1051 \leq n \leq 10^51≤n≤105)–Superhero的攻击力、Superhero的初始健康值和怪物数量。
- 每个测试案例的第二行包含nnn个整数a1,a2,…ana_1, a_2, \dots a_na1,a2,…an(1≤ai≤1061 \leq a_i \leq 10^61≤ai≤106),其中表示第iii个怪物的攻击力。
- 每个测试用例的第三行包含nnn个整数b1,b2,…bnb_1, b_2, \dots b_nb1,b2,…bn(1≤bi≤1061 \leq b_i \leq 10^61≤bi≤106),其中表示第iii个怪物的初始健康值。
- 保证所有测试案例的nnn之和不超过10510^5105。
输出格式
对每个测试案例输出答案。输出YES表示伟大的Superhero能杀死所有的怪物。
否则,输出 NO。
样例输入
5
3 17 1
2
16
10 999 3
10 20 30
100 50 30
1000 1000 4
200 300 400 500
1000 1000 1000 1000
999 999 1
1000
1000
999 999 1
1000000
999
样例输出
YES
YES
YES
NO
YES
提示
在第一个样例中,Superhero和唯一的怪物会有666次战斗。之后,怪物死亡,Superhero的健康值变成17−6×2=5>017-6×2=5>017−6×2=5>0,所以答案是 “YES”,而且,Superhero还活着。
在第二个例子中。无论战斗顺序如何,当所有的怪物都死了之后 Superhero的健康值会变成 709709709, 所以答案是 “YES”。
在第三个例子中。一个可能的顺序是与第一个,第二个,第三个,第四个怪物战斗。所有战斗结束后,Superhero的健康值变成−400-400−400。不幸的是,Superhero死了,但所有的怪物也都死了。所以答案是 “YES”。
在第四个例子中。Superhero死了,但怪物还活着,健康值为1000−999=11000 -999=11000−999=1。所以答案是 “NO”。
我们先考虑怎么杀怪物:
我们肯定是先杀生命值小的。
所以我们需要按照怪兽的攻击力从小到大排序,如果攻击力相同则生命力小的在前面。
然后我们就来刷怪。
如果我并没有刷到最后一只怪,但是我死了,就输出NO。
如果我最后一刀杀出去了,然后我再死的,就说明我把怪杀完了,输出YES。
如果我最后一刀杀出去了,然后我并没死的,就说明我把怪杀完了,也输出YES。
*但是谁也没有来 =)
所以我们的代码就这么写:
排序函数&结构体:
struct monster {
int atk, blood;
bool operator<(const monster &t)const {
if(atk == t.atk)
return blood < t.blood;
return atk < t.atk;
}
}mon[100010];
刷怪的过程:
for(int i = 1; i <= n; i++)
{
if(ceil(b * 1.0 / mon[i].atk) * a > mon[i].blood)
b -= ceil(mon[i].blood * 1.0 / a) * mon[i].atk;
else if(ceil(b * 1.0 / mon[i].atk) * a == mon[i].blood && i == n)
b -= ceil(mon[i].blood * 1.0 / a) * mon[i].atk;
else
{
flag = false;
printf("NO\n");
break;
}
}
if(flag)
printf("YES\n");
完整代码:
#include <bits/stdc++.h>
using namespace std;
struct monster {
int atk, blood;
bool operator<(const monster &t)const {
if(atk == t.atk)
return blood < t.blood;
return atk < t.atk;
}
}mon[100010];
int t;
int main()
{
scanf("%d",&t);
int a, b, n;
bool flag = false;
while(t--)
{
scanf("%d %d %d", &a, &b, &n);
for(int i = 1; i <= n; i++)
scanf("%d", &mon[i].atk);
for(int i = 1; i <= n; i++)
scanf("%d", &mon[i].blood);
sort(mon + 1, mon + 1 +n);
for(int i = 1; i <= n; i++)
{
if(ceil(b * 1.0 / mon[i].atk) * a > mon[i].blood)
b -= ceil(mon[i].blood * 1.0 / a) * mon[i].atk;
else if(ceil(b * 1.0 / mon[i].atk) * a == mon[i].blood && i == n)
b -= ceil(mon[i].blood * 1.0 / a) * mon[i].atk;
else
{
flag = false;
printf("NO\n");
break;
}
}
if(flag)
printf("YES\n");
}
return 0;
}
完结撒花~~~~~
本文介绍了一位名为Superhero的英雄与怪物战斗的模拟问题,Superhero需要通过策略攻击怪物,直到消灭所有怪物或自己死亡。文章讨论了如何根据怪物的攻击力和生命值进行排序,并采取相应策略进行战斗,最终给出解决问题的代码实现。
2850

被折叠的 条评论
为什么被折叠?



