题目:click
题意:你有一支军队n个人,每个人有相应的攻击力,防御力,敌人m人,每个人有相应的攻击力,防御力。a的攻击力比b的防御力大与等于那么就能够杀死b时相互的,问我方最多能存活多少人,每人只能出战一次。
看到题目的范围贪心+排序,可以将敌人的防御力从大到小先排序,我方的攻击力从大到小排好序,比方说遇到敌人i,我们先找到比i的防御力大的兵,如果没有输出-1,之后我们找一个防御力比i的攻击力大一点的肯定优先去打,需要二分,插入我方人员时需要log(n)的插入以及排好序直接利用multiset容器,在容器内查找即可,如果没有防御力大于i的攻击力的,那么把最小的防御力的跟敌人同归于尽贪心。
#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define llinf 0x3f3f3f3f3f3f3f3f
using namespace std;
typedef long long ll;
const int MAXN=262144*2+10;
const double PI=acos(-1.0);
const long double eps=1e-12;
struct A {
int att,den;
}a[100100],b[100100];
bool cmp1(A t1,A t2)
{
return t1.den>t2.den;
}
bool cmp2(A t1,A t2)
{
return t1.att>t2.att;
}
int main()
{
int yy=1;
int T;
scanf("%d",&T);
while(T--)
{
int n,m,i,j;
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
scanf("%d %d",&a[i].att,&a[i].den);
for(i=0;i<m;i++)
scanf("%d %d",&b[i].att,&b[i].den);
sort(b,b+m,cmp1);
sort(a,a+n,cmp2);
multiset<int>hh;
hh.clear();
int ans=n;
multiset<int>::iterator it;
for(j=0,i=0;j<m;j++)
{
while(i<n&&a[i].att>=b[j].den)
{
hh.insert(a[i].den);
i++;
}
if(hh.empty())
{
ans=-1;
break;
}
it=hh.upper_bound(b[j].att);
if(it==hh.end())
{
hh.erase(hh.begin());
ans--;
continue;
}
hh.erase(it);
}
printf("Case #%d: %d\n",yy++,ans);
}
return 0;
}
/*
2
3 2
5 7
7 3
1 2
4 4
2 2
2 1
3 4
1 10
5 6
*/