Incinerate

题目连接:

Problem - B - Codeforces


题目描述

为了毁灭人类,怪物协会向地球表面派出了 nn 只怪物。第 ii 只怪物拥有 hih_i 的健康和 pip_i 的力量。

杰诺斯的最后一击是 “真螺旋焚化炮”,它可以对所有活着的怪物造成 kk 的伤害。换句话说,杰诺斯一次攻击就能使所有怪物的生命值降低 kk (如果 k>0k > 0 )。

然而,杰诺斯每次攻击后,怪物们都会前进。在它们的共同努力下,杰诺斯的攻击伤害会减少 最弱怪物的生命值。也就是说,每次攻击后,kk 的数值都会减去当前所有存活怪物中最小的 pip _ i

吉诺斯能成功杀死所有怪物吗?

输入描述

输入的第一行包含一个整数 tt ( 1t1001 \le t \le 100 ) 测试用例的数量。测试用例说明如下。

每个测试用例的第一行包含两个整数 nnkk ( 1n,k1051 \le n, k \le 10^5 )。( 1n,k1051 \le n, k \le 10^5 )–怪物数量和基诺斯的初始攻击伤害。随后两行分别包含 nn 个整数,描述了数组 hhpp ( 1hi,pi1091 \le h _ i, p _ i \le 10^9 )。

保证所有测试用例的 nn 之和不超过 21052 \cdot 10^5

输出描述

对于每个测试用例,如果 Genos 能杀死所有怪物,则打印答案 “YES”(不带引号),否则打印 “NO”。

示例

输入

text
1
2
3
4
5
6
7
8
9
10
3
6 7
18 5 13 9 10 1
2 7 2 1 2 6
3 4
5 5 5
4 4 4
3 2
2 1 3
1 1 1

输出

text
1
2
3
YES
NO
YES

说明

在第一个示例中,吉诺斯第一次攻击后, h 和 k 将更新为:

  • h:[11,0,6,2,3,0]h: [11,0,6,2,3,0]
  • k:71=6k: 7-1 = 6

第二次攻击后

  • h:[5,0,0,0,0,0]h: [5,0,0,0,0,0]
  • k:62=4k: 6-2 = 4

第三次攻击后

  • h:[1,0,0,0,0,0]h: [1,0,0,0,0,0]
  • k:42=2k: 4-2 = 2

第四次攻击后

  • h:[0,0,0,0,0,0]h: [0,0,0,0,0,0]

由于基诺斯可以杀死所有怪物,所以答案是 “YES”。


题解

这道题主要用到了排序算法,我们有两种排序方法,第一种是对怪兽的生命值进行排序,另一种是对怪兽的力量进行排序。

解法一

首先我们来看第一种排序方法,对怪物按健康状况从高到低排序。

现在,我们要对每次攻击后存活的怪物进行计数。这可以通过为每次攻击在 hh 数组上应用 upperbound( ) 来实现。受到的总伤害可以存储在一个单独的变量中并进行更新。

若要找出存活的最弱怪物的威力,我们只需预先计算后缀数组中怪物的最小威力。换句话说,也就是 pi=min(pi,pi+1)pi=min(pi,pi+1)

时间复杂度: O(nlogn)O(nlogn)

解法二

我们呢再来看第二种排序方法,对怪物的力量从低到高排序,只有生命值大于总伤害值的怪物才算活着,而每次遇到这样的怪物时,它都是当前最弱的一个,因此我们需要攻击,直到总伤害值超过当前怪物的生命值。

如果在伤害降为0之前能杀死,也就是遍历到最后一个怪物,答案就是“YES”,否则就是“NO”。

时间复杂度: O(nlogn)O(nlogn) 。

下面给出第二种方法的完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<bits/stdc++.h>
using namespace std;
struct g1
{
int h;
int p;
}g[100005];

bool cmp(g1 a,g1 b)
{
return a.p<b.p;
}

void solve()
{
long long n,k;
bool flag=true;
cin>>n>>k;
for (int i=1;i<=n;i++)
{
cin>>g[i].h;
}
for (int i=1;i<=n;i++)
{
cin>>g[i].p;
}
sort (g+1,g+n+1,cmp);
int i=1;
long long ans=k;
while(i<=n)
{
if (g[i].h>k)
{
ans-=g[i].p; //当前伤害
k=k+ans; //累计伤害
}
else
{
i++;
}
if (ans<0)
{
flag=false;
break;
}
}

if (flag)
{
cout<<"YES"<<endl;
}
else
{
cout<<"NO"<<endl;
}
return ;
}

int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin>>t;
while (t)
{
t--;
solve();
}
}

Incinerate
https://serendipity565.github.io/posts/ea65d96e9580/
作者
Serendipity
发布于
2024年3月31日
许可协议
BY-SERENDIPITY565