HDU4268 2012ACM长春赛区网络赛 Alice and Bob

题目:HDU4268(贪心)

题意是Alice和Bob都有N张卡片,卡片各有尺寸,Alice拿自己的卡片分别去盖Bob的,给出每张卡片的尺寸,问最多可以盖住多少张。

先说一下我错误的解题方法,主要思想就是拿最大的去盖最大的。分别对Alice和Bob的卡片在两个set中进行排序(排序是自动的),

按卡片的h降序排,h相同时按w的降序排。然后以Bob的set做循环,取Alice的set首端的卡片去盖,能盖住则删去,代码如下:

#include <iostream>
//#include <fstream>
#include <set>
#define FOR(a,b) for(int i = (a);i < (b);i ++)
using namespace std;

class Card
{
public:
    int h,w;
    bool operator<(const Card& c) const //插入set时自动排序,要自定义"<"操作符
    {
        if( h == c.h) return w < c.w;
        return h < c.h;
    }
    bool CanCover(const Card& c) const
    {
        return (h >= c.h && w >= c.w);
    }    
};

int main()
{
    //ifstream cin("in.txt");
    multiset<Card> Alice,Bob;
    multiset<Card>::iterator ap,bp;
    Card c;
    int t,n,ans;
    cin>>t;
    while (t --)
    {
        Alice.clear();
        Bob.clear();
        ans = 0;

        cin>>n;
        FOR(0,n)
        {
            cin>>c.h>>c.w;
            Alice.insert(c);
        }
        FOR(0,n)
        {
            cin>>c.h>>c.w;
            Bob.insert(c);
        }

        ap = Alice.begin();
        while (ap != Alice.end())
        {
            bp = Bob.begin();
            if(ap->CanCover(*bp))
            {
                Bob.erase(bp);
                ans ++;
            }
            ap ++;
        }
        cout<<ans<<endl;
    }
}

我拿着这个代码提交了好几次都不对,然后就去参考了牛人的博客,看了半天才发现自己陷入了思维定势,正确思维应该是,对于Bob的每张卡片,把Alice的满足高度大于这张卡片的所有卡片组成一个集合(set),从集合中找w最接近的卡片,找到则从集合中删去。

正确的代码如下:

#include <iostream>
//#include <fstream>
#include <set>
#include <algorithm>
#define FOR(a,b) for(int i = (a); i < (b); i ++)
using namespace std;
const int maxnum = 100005;

struct Card
{
    int h,w;
    bool operator<(Card& c)
    {
        return (h < c.h);
    }
};

Card Alice[maxnum],Bob[maxnum];

int main()
{
    //ifstream cin("in.txt");
    multiset<int> mi;
    multiset<int>::iterator mit;
    int t,n,ans;
    cin>>t;
    while (t --)
    {
        cin>>n;

        memset(Alice,0,sizeof(Card)*n);
        memset(Bob,0,sizeof(Card)*n);
        mi.clear();
        ans = 0;

        FOR(0,n)
        {
            cin>>Alice[i].h>>Alice[i].w;
        }
        FOR(0,n)
        {
            cin>>Bob[i].h>>Bob[i].w;
        }

        sort(Alice,Alice+n);
        sort(Bob,Bob+n);

        int p = 0;
        FOR(0,n)
        {            
            while (p < n && Bob[p].h <= Alice[i].h)
            {
                mi.insert(Bob[p].w);
                p ++;
            }
            if(mi.size())
            {
                mit = mi.lower_bound(Alice[i].w);
                if(mit == mi.end()) mit --;
                if(mit != mi.begin() && Alice[i].w < *mit) mit --;
                if(Alice[i].w >= *mit)
                {
                    mi.erase(mit);
                    ans ++;
                }
            }
        }
        cout<<ans<<endl;
    }
}
posted @ 2012-09-28 00:25  iFinVer  阅读(233)  评论(0编辑  收藏  举报