亚洲区长春站网络赛第2题
题意:Alice和Bob各有n张卡片,如果卡片a的宽和高都不小于卡片b,则a能覆盖b,问Alice的卡片最多能覆盖多少Bob的卡片。每张卡片只能用一次,每张最多只能覆盖一张。
分析:在这里卡片之间的关系有3种,1、a能覆盖b;2、b能覆盖a;3、a不能覆盖b,b不也覆盖不了a(a和b相同的情况可以并入前面2种)。我们将双方卡片排序(先比较高,然后比较宽,小的在前)后,若Alice最小的卡片不能覆盖Bob最小的卡片,则Alice这张卡片可以直接抛弃,如果能覆盖,则一定要覆盖一个宽度最大的。我们将Bob的卡片中高度比它小的存入set(关键字为最大宽度-自身宽度),要注意相同卡片的处理(貌似第一次没处理也过了),然后使用set的成员函数lower_bound()就能找到最优的那个。
View Code
#include <stdio.h> #include <algorithm> #include <set> using namespace std; #define N 100001 struct card { int h,w; card(){} card(int h1,int w1){h=h1,w=w1;} bool operator<(const card &t) const { return h<t.h || h==t.h&&w<t.w; } }a[N],b[N]; struct pro { int n,INF,ans; set<card> S; set<card>::iterator pos; pro(){INF=1000000000,ans=0;} void read() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d%d",&a[i].h,&a[i].w); for(int i=0;i<n;i++) scanf("%d%d",&b[i].h,&b[i].w); } void solve() { sort(a,a+n); sort(b,b+n); for(int i=0,j=0;i<n;i++) { while(j<n && b[j].h<=a[i].h) S.insert(card(INF-b[j].w,j)),j++;//第二维能区分相同卡片 pos=S.lower_bound(card(INF-a[i].w,0)); if(pos!=S.end()) { S.erase(pos); ans++; } } printf("%d\n",ans); } }; int main() { int t; scanf("%d",&t); while(t--) { pro p; p.read(); p.solve(); } return 0; }