链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1916
Description:
小w和小z想到了一个新游戏,在这个游戏中他们各有N个卡片。小w想去使用她的卡片去覆盖小z的卡片。
卡片A能覆盖卡片B的条件是卡片A的高不小于卡片B的高同时卡片A的宽不小于卡片B的宽。
现在请计算出小w的牌最多能覆盖小z的牌的数量。注意牌只能被使用一次,并且牌不能被旋转。
Input:
第一行是一个整数t代表测试数据组数。
对于每组测试数据第一行是一个整数n(n<=100000)代表卡片数量。
接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小w的卡片的高和宽。
在接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小z的卡片的高和宽。
Output:
对于每组测试数据,输出小w的牌最多能覆盖小z的牌的数量。
Sample Input:
2
2
1 2
3 4
2 3
4 5
3
2 3
5 7
6 8
4 1
2 5
3 4
Sample Output:
1
2
听几个亚洲区得过奖的师兄说,这是一道亚洲区的题目,记得当时自己刚看到这道题的时候,还是不好下手,过了不知道多久,然后再拿出来看了一下,A了,,嘻嘻,,还是挺难的这道题,方法确实很难想到,这道题过的人只有几个。。。还是挺不容易的说真的。。。
其实看我代码你就会知道这道题大概的想法,,代码写的比较容易。。。如果还是没看懂,,那私聊。。。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <algorithm>
#define MAXN 200000+10
using namespace std;
typedef struct Node_
{
int x, y;
int flag;
}Node;
Node N[MAXN];
int n, cas;
multiset <int> s;
multiset <int> :: iterator it;
void Init()
{
scanf("%d", &n);
for(int i=0; i<2*n; i++) {
scanf("%d %d", &N[i].x, &N[i].y);
if(i < n) N[i].flag = 0;
else N[i].flag = 1;
}
s.clear();
}
bool cmp(const Node a, const Node b)
{
if(a.x != b.x) return a.x < b.x;
else if(a.y != b.y) return a.y < b.y;
else return a.flag > b.flag;
}
int main()
{
scanf("%d", &cas);
while(cas--) {
Init();
int cnt = 0;
sort(N, N+(2*n), cmp);
for(int i=0; i<2*n; i++) {
if(N[i].flag == 1) s.insert(N[i].y);
else if(!s.empty()) {
if(*s.begin() <= N[i].y) {
it = s.upper_bound(N[i].y);
it--;
cnt++;
s.erase(it);
}
}
}
printf("%d\n", cnt);
}
return 0;
}