codeforces day 4(含set的使用)

其实每天都有写的了,但是有动力去写博客的时间真的很少。

Problem - 1763B - Codeforces

B. Incinerate

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

To destroy humanity, The Monster Association sent nn monsters to Earth's surface. The ii-th monster has health hihi and power pipi.

With his last resort attack, True Spiral Incineration Cannon, Genos can deal kk damage to all monsters alive. In other words, Genos can reduce the health of all monsters by kk (if k>0k>0) with a single attack.

However, after every attack Genos makes, the monsters advance. With their combined efforts, they reduce Genos' attack damage by the power of the ††weakest monster ‡‡alive. In other words, the minimum pipi among all currently living monsters is subtracted from the value of kk after each attack.

††The Weakest monster is the one with the least power.

‡‡A monster is alive if its health is strictly greater than 00.

Will Genos be successful in killing all the monsters?

Input

The first line of the input contains a single integer tt (1≤t≤1001≤t≤100) — the number of test cases. The description of test cases follows.

The first line of each test case contains two integers, nn and kk (1≤n,k≤1051≤n,k≤105) — the number of monsters and Genos' initial attack damage. Then two lines follow, each containing nn integers describing the arrays hh and pp (1≤hi,pi≤1091≤hi,pi≤109).

It's guaranteed that the sum of nn over all test cases does not exceed 2⋅1052⋅105.

Output

For each test case, print the answer — "YES" (without quotes) if Genos could kill all monsters and "NO" otherwise.

Example

input

Copy

 

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

output

Copy

YES
NO
YES

Note

In the first example, after Genos' first attack, hh and kk will update to:

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

After second attack:

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

After third attack:

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

After fourth attack:

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

As Genos could kill all monsters, the answer is YES.

翻译:Incinerate - 洛谷

先来看我的暴力写法吧,连第二个测试点都过不了,这个不需要去看。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 20010;
int p[N], h[N], st[N];

int main() {
	int  t;
	cin >> t;
	while (t--) {
		int n, k;
		cin >> n >> k;
		for (int i = 1; i <= n; i++) {
			st[i] = 0;
		}
		for (int i = 1; i <= n; i++) {
			cin >> h[i];
		}
		for (int i = 1; i <= n; i++) {
			cin >> p[i];
		}
		while (k > 0) {
			for (int i = 1; i <= n; i++) {
				h[i] -= k;

				if (h[i] <= 0)
					st[i] = 1;
			}
			int minx = p[1];
			for (int i = 1; i <= n; i++) {
				if (!st[i])
					minx = min(p[i], minx);

			}
			k -= minx;

		}

		int hh = 1;
		for (int i = 1; i <= n; i++) {
			if (!st[i]) {
				printf("NO\n");
				hh = 0;
				break;
			}
		}
		if (hh)
			printf("YES\n");
	}
	return 0;
}

我们来分析题意,这道题的意思就是每一次都要将怪兽的生命值减去值为k的生命,并且将所有还活着的怪兽的最小攻击值用k减去然后继续这样的操作,直到怪物死光,或者k值小于等于0

然后我们就从中得出了几个关键的思路。

第一:我们要用怪兽的生命值减去k;

第二:k的每次迭代与还存活着的怪兽中最小的生命值有关。

注意到关键词,一个存活,一个最小,只要实现这两个关键点就可以完成本题,于是,本弱学到了一个新的东西set。

set是什么呢?

set是一个自动去重且有序元素集合,于是我们可以利用此来进行排序。

考虑到有两个元素在这个集合中,我们可以用pair数组来进行维护,因此我们可以得到一个同时包含两个元素的结构体。

然后,我们还要创建两个set。为什么要有两个set呢?因为我们要对两个关键字进行排序,一个以生命为关键字,一个以攻击力为关键字。pair数组的作用set的作用在此刻都体现了出来。我们可以用一个为0的生命值数据进行两个set中的互相清零清除。

即我们第一个set中的hp=0之后,我们可以用这个关键字去第二个set中清除掉,并且set还能在同时自动排序,得到最小的那个攻击值。

还有几个要点要注意,那就是我们千万要注意在define int 之后熟悉的int  main就不能使用了,千万注意。

代码如下,解释很详细

#include <bits/stdc++.h>
using namespace std;
#define int long long
int t;
int n, k;
const int N = 200010;
int h[N], p[N];
set<pair<int, int>>s1, s2;
 
//silentzdw刷了两小时的题
main() {
	std::cin.tie(0);
	std::ios::sync_with_stdio(0);
	cin >> t;
	while (t--) {
		s1.clear();
		s2.clear();//注意清空整个set否则可能会保留前一个set的值。
 
		cin >> n >> k;
		for (int i = 1; i <= n; i++) {
			cin >> h[i];
		}
		for (int i = 1; i <= n; i++) {
			cin >> p[i];
			s1.insert(make_pair(h[i], p[i])); //s1以hp为第一关键字排序,加入怪兽信息
			s2.insert(make_pair(p[i], h[i])); //s2以攻击力为第一关键字排序,加入怪兽信息
 
		}
		int x = 0; //不用每一次迭代去将每一个怪兽的生命值去减少,只用一个x累加攻击力来判断当前怪兽的生命值是否已经需要被移除。
		while (!s1.empty() && k > 0) {
			x += k; //同上,累加攻击力。
			while (!s1.empty() && (*s1.begin()).first <= x) {
				int l = (*s1.begin()).first;
				//执行就意味着他的生命值已经小于x需要被移除。
				int r = (*s1.begin()).second;//l,r分别记录两个关键字,因为erase在移除时需要用数字的值来进行检索。
				s1.erase(s1.begin());
				s2.erase(s2.find(make_pair(r, l))); //由于在 s2 中攻击力是第一关键字,所以这里 l 和 r 的顺序要颠倒。
			}
			k -= (*s2.begin()).first;
		}
		if (s1.empty())
			printf("YES\n");
		else
			printf("NO\n");
 
	}
 
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值