http://acm.hdu.edu.cn/showproblem.php?pid=4268
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
/** hdu 4268 multiset应用 题目大意:一牌,如果他的长和宽都分别不小于另一张,那么这张牌就可以覆盖另一张,问在A的牌中,有多少 可以覆盖B的牌(一张牌只能覆盖一张,并且长宽已给出,并不一定长度大的的就是长) 解题思路:这道题的数据如果小一点,完全可以用二分图来做。对AB的牌进行排序长递增,然后枚举A的牌,把所有B 的牌大于A的长的加入multiset里,利用lower_bound()找出宽最小的一个,然后删除该元素。复杂度O(n*logn) */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #include <set> using namespace std; const int maxn=100005; int n; multiset <int> s; struct note { int x,y; bool operator < (const note &other)const { return x<other.x; } }a[maxn],b[maxn]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d",&a[i].x,&a[i].y); } for(int i=0;i<n;i++) { scanf("%d%d",&b[i].x,&b[i].y); } sort(a,a+n); sort(b,b+n); s.clear(); int k=0,ans=0; for(int i=0;i<n;i++) { while(a[i].x>=b[k].x&&k<n) { s.insert(b[k].y); k++; } if(s.empty())continue; multiset<int>::iterator it=s.lower_bound(a[i].y); if(it==s.end()||a[i].y<*it)it--; if(*it<=a[i].y) { ans++; s.erase(it); } } printf("%d\n",ans); } return 0; }