HDOJ 4268 Alice and Bob (set的应用)

亚洲区长春站网络赛第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;
}
原文地址:https://www.cnblogs.com/algorithms/p/2679056.html