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.
OutputFor each test case, output an answer using one line which contains just one number.
Sample Input
2 2 1 2 3 4 2 3 4 5 3 2 3 5 7 6 8 4 1 2 5 3 4Sample Output
1 2
A有n張不同的卡片,B也有n張不同的卡片,其中每個卡片只能用一次(即A的一張卡片只能覆蓋一張B的卡片),問你A最多可以覆蓋B的多少張卡片.
思路:
對兩個集合按照x進行升序排序,然後對a集合中的每個物品,在x滿足的情況下,將對應的b集合中的物品扔入multiset中,然後在multiset中尋找y值最大的合法值,若找到++ans並將該值erase;
這裏有坑,可以選用upper_bound簡化代碼,在之前應搞清楚upper_bound 與 lower_bound 的區別,推薦一下我的一點博客可以自找一下,還有就是注意迭代器不要越界.
上代碼:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int T;
multiset<int> op;
struct node{
int x;
int y;
};
node a[100001];
node b[100001];
bool cmp(node c,node d)
{
return c.x < d.x;
}
int main()
{
scanf("%d" ,&T);
int n;
while(T--)
{
scanf("%d", &n);
for(int i=1; i<=n; i++)
{
scanf("%d %d",&a[i].x, &a[i].y);
}
for(int i=1; i<=n; i++)
{
scanf("%d %d",&b[i].x,&b[i].y);
}
sort(a+1,a+1+n,cmp);
sort(b+1,b+1+n,cmp);
op.clear();
int j = 1;
int sum = 0;
for(int i=1; i<=n; i++)
{
for( ; j<=n; j++)
{
if(a[i].x >= b[j].x)
{
op.insert(b[j].y);
}
else break;
}
if(op.empty())continue;
multiset<int>::iterator it = op.upper_bound(a[i].y);
if(it == op.begin()){continue;}
if(*--it <= a[i].y){sum++; op.erase(it);}
}
printf("%d\n",sum );
}
return 0;
}
水波.