题意:
你有n个攻击力为A,防御力为D的兽人,敌人有m个攻击力为EA,防御力为ED的兽人,两个兽人在对战时同时攻击对方,当攻击力高于对方的防御力时,即可杀死对方。你的兽人只能用一次。问你在杀死所有敌人的前提下你的兽人最多能剩多少。
思路:
将我们的兽人按攻击力A从大到小排列,敌人按防御力D从大到小排列,然后枚举每只敌人,将能杀死他也就是攻击力高于他的兽人防御力丢到一个multiset中,对于当前敌人,在multiset中找一个D刚好大于他攻击力的我们的兽人来干他,如果找不到大于他攻击力的就取一个防御力最小的和他同归于尽。这样做总是最优的。
#include<cstdio>
#include<set>
#include<algorithm>
using namespace std;
const int MAX=1e5+5;
int n,m;
multiset<int> s;
multiset<int>::iterator it;
struct Node{
int A,D;
}a[MAX],b[MAX];
bool cmp1(Node a,Node b){
return a.A>b.A;
}
bool cmp2(Node a,Node b){
return a.D>b.D;
}
int main(){
int T,cas=1;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d%d",&a[i].A,&a[i].D);
}
for(int i=0;i<m;i++){
scanf("%d%d",&b[i].A,&b[i].D);
}
sort(a,a+n,cmp1);
sort(b,b+m,cmp2);
int ans=n,j=0;
bool flag=true;
s.clear();
for(int i=0;i<m;i++){
for(;j<n;j++){
if(b[i].D<=a[j].A){
s.insert(a[j].D);
}
else break;
}
if(s.empty()){
flag=false;
break;
}
it=s.upper_bound(b[i].A);
if(it==s.end()) it=s.begin(),ans--;
s.erase(it);
}
printf("Case #%d: ",cas++);
if(flag) printf("%d\n",ans);
else printf("-1\n");
}
return 0;
}