Alice and Bob
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4751 Accepted Submission(s): 1487
Please pay attention that each card can be used only once and the cards cannot be rotated.
For each case, the first line is a number N which means the number of cards that Alice and Bob have respectively. Each of the following N (N <= 100,000) lines contains two integers h (h <= 1,000,000,000) and w (w <= 1,000,000,000) which means the height and width of Alice's card, then the following N lines means that of Bob's.
2 2 1 2 3 4 2 3 4 5 3 2 3 5 7 6 8 4 1 2 5 3 4
1 2
题意:给出Alice和Bob的卡牌的长度和宽度,问Alice可以覆盖多少张Bob的卡牌(一张只能使用一次),覆盖是长度和宽度都大于等于Bob的卡牌的长宽
分析:暴力的话O(n^2)会超时的,可以先将x按降序排(后面排的x一定是小于前面的x),如果x相等则按y的降序排。这样只需要比较y就可以了。
然后用跑一次,如果是Alice的卡,就将y加入multiset里,否则则查询multiset里是否有比Bob的y大的。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
#define MAX_N 100005
using namespace std;
struct node
{
int x,y;
int id;
}a[2*MAX_N];
bool cmp(node a,node b)
{
if(a.x==b.x&&a.y==b.y)
return a.id<b.id;
if(a.x!=b.x)
return a.x>b.x;
return a.y>b.y;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].id=1;
}
for(int i=n+1;i<=2*n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].id=2;
}
sort(a+1,a+1+2*n,cmp);
multiset<int> s;
int cnt=0;
for(int i=1;i<=2*n;i++)
{
if(a[i].id==1)
{
s.insert(a[i].y);
}
else
{
multiset<int> ::iterator it=s.lower_bound(a[i].y);
if(it==s.end())
continue;
else
{
cnt++;
s.erase(it);
}
}
}
printf("%d\n",cnt);
}
return 0;
}
1万+



被折叠的 条评论
为什么被折叠?



