链接: 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; }
HLG 1916 小Z的卡片 (set 难题)恏似系亚洲区噶题,布布扣,bubuko.com
时间: 2024-10-13 15:06:41