首页 > 代码库 > HLG 1916 小Z的卡片 (set 难题)恏似系亚洲区噶题

HLG 1916 小Z的卡片 (set 难题)恏似系亚洲区噶题

链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1916

Description:

小w和小z想到了一个新游戏,在这个游戏中他们各有N个卡片。小w想去使用她的卡片去覆盖小z的卡片。

卡片A能覆盖卡片B的条件是卡片A的高不小于卡片B的高同时卡片A的宽不小于卡片B的宽。

现在请计算出小w的牌最多能覆盖小z的牌的数量。注意牌只能被使用一次,并且牌不能被旋转。

Input:

第一行是一个整数t代表测试数据组数。

对于每组测试数据第一行是一个整数n(n<=100000)代表卡片数量。

接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小w的卡片的高和宽。

在接下来n行每行两个整数h(h<=1000000000)和w(w<=1000000000)代表小z的卡片的高和宽。

Output:

对于每组测试数据,输出小w的牌最多能覆盖小z的牌的数量。

Sample Input:

2
2
1 2
3 4
2 3
4 5
3
2 3
5 7
6 8
4 1
2 5
3 4
Sample Output:

1

2


听几个亚洲区得过奖的师兄说,这是一道亚洲区的题目,记得当时自己刚看到这道题的时候,还是不好下手,过了不知道多久,然后再拿出来看了一下,A了,,嘻嘻,,还是挺难的这道题,方法确实很难想到,这道题过的人只有几个。。。还是挺不容易的说真的。。。


其实看我代码你就会知道这道题大概的想法,,代码写的比较容易。。。如果还是没看懂,,那私聊。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <algorithm>
#define MAXN 200000+10
using namespace std;

typedef struct Node_
{
    int x, y;
    int flag;
}Node;

Node N[MAXN];
int n, cas;
multiset <int> s;
multiset <int> :: iterator it;

void Init()
{
    scanf("%d", &n);
    for(int i=0; i<2*n; i++) {
        scanf("%d %d", &N[i].x, &N[i].y);
        if(i < n) N[i].flag = 0;
        else N[i].flag = 1;
    }
    s.clear();
}

bool cmp(const Node a, const Node b)
{
    if(a.x != b.x) return a.x < b.x;
    else if(a.y != b.y) return a.y < b.y;
    else return a.flag > b.flag;
}

int main()
{
    scanf("%d", &cas);
    while(cas--) {
        Init();
        int cnt = 0;
        sort(N, N+(2*n), cmp);
        for(int i=0; i<2*n; i++) {
            if(N[i].flag == 1) s.insert(N[i].y);
            else if(!s.empty()) {
                if(*s.begin() <= N[i].y) {
                    it = s.upper_bound(N[i].y);
                    it--;
                    cnt++;
                    s.erase(it);
                }
            }
        }
        printf("%d\n", cnt);
    }
    return 0;
}