题意

  • 有n支军队,m支敌人,每支军队攻击力比对方高就可以消灭对方,同时减少对方攻击力的防御力,每只军队只能进攻一个敌人,能否消灭所有敌人,消灭敌人后最多剩多少军队

思路

  • 贪心的思考,在已知敌人防御力的情况下,我们希望存活,所以使用刚刚好大一点的军队,去消灭他,如果最大都不够消灭,就选择防御力最低的去同归于尽。
  • 军队按照攻击力降序排,敌人按照防御力降序排,对于每一个敌人,挑出所有可以消灭他的军队,如果同归于尽,就给损耗加一。最终答案是n-损耗。特别地,如果对于任意一个敌人,没有攻击力比他更大的军队,就说明无法消灭。
  • 对于存放比敌人防御力高的军队,需要能够查找,排序,存重复,故选用multiset,同时使用upper_bound找第一个防御力大于敌人的我方军队

AC代码

#include<bits/stdc++.h>
using namespace std;
pair<int, int> a[202020],b[202022];
bool cmp1(pair<int,int> a,pair<int,int> b){return a.first>b.first;}
bool cmp2(pair<int,int> a,pair<int,int> b){return a.second>b.second;}
int main(){
	int t;
	scanf("%d",&t);
	for(int k=1;k<=t;k++){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=0;i<n;i++)scanf("%d%d",&a[i].first,&a[i].second);
		for(int i=0;i<m;i++)scanf("%d%d",&b[i].first,&b[i].second);
		sort(a,a+n,cmp1);
		sort(b,b+m,cmp2);
		int j=0,jg=1,ans=0;
		multiset<int>s;
        s.clear();
		for(int i=0;i<m;i++){
			for(;a[j].first>=b[i].second&&j<n;j++){
				s.insert(a[j].second);
			}
			if(s.empty()){jg=0;break;}
			if(*--s.end()<=b[i].first){
				s.erase(s.begin());
				ans++;
			}else{
				s.erase(s.upper_bound(b[i].first));
			}
		}
		printf("Case #%d: %d\n",k,jg?n-ans:-1);
	}
	
	return 0;
}