昨晚打了第一场atcoder...这题卡了1h...今天听课的时候听到了一个极相似的题。。。
题意:给出2n个点的坐标(x,y) 前n个是红点,剩下是蓝点,当一个红点的横纵坐标都小于一个蓝点的时候,他们可以匹配,求最大的匹配对数
按照横坐标排序,排序后从右往左扫描,发现蓝点将其纵坐标存入set中(因为已经按照横坐标排序,所以不需要考虑横坐标),发现红点从set中找一个能跟这个点匹配的最小的点(lower_bound),注意set::lower_bound是O(logn)的,std::lower_bound在set中是O(n)的,因为set不支持随机访问
还能用二分图匹配,但是数据范围大了似乎只能用这种方法
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef pair<int, int> pii; 4 set<int>s; 5 struct Node { 6 int x, y, color; 7 inline bool operator < (const Node & rhs) const {return x < rhs.x;} 8 }Node[300]; 9 int n, ans; 10 int main(void){ 11 scanf("%d", &n); 12 for(int i = 1; i <= n; ++i) scanf("%d%d", &Node[i].x, &Node[i].y), Node[i].color = 1; 13 for(int i = 1; i <= n; ++i) scanf("%d%d", &Node[i+n].x, &Node[i+n].y), Node[i+n].color = 2; 14 sort(Node+1, Node+1+n*2); 15 for(int i = 2*n; i >= 1; --i) { 16 if (Node[i].color == 2) s.insert(Node[i].y); 17 else { 18 auto it = s.lower_bound(Node[i].y); 19 if (it != s.end()) s.erase(it), ans++; 20 } 21 } 22 cout << ans; 23 return 0; 24 }