1. 程式人生 > >HDU4268 Alice and Bob【貪心+SET】

HDU4268 Alice and Bob【貪心+SET】

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4719    Accepted Submission(s): 1480

Problem Description Alice and Bob's game never ends. Today, they introduce a new game. In this game, both of them have N different rectangular cards respectively. Alice wants to use his cards to cover Bob's. The card A can cover the card B if the height of A is not smaller than B and the width of A is not smaller than B. As the best programmer, you are asked to compute the maximal number of Bob's cards that Alice can cover.
Please pay attention that each card can be used only once and the cards cannot be rotated.
Input The first line of the input is a number T (T <= 40) which means the number of test cases.
For each case, the first line is a number N which means the number of cards that Alice and Bob have respectively. Each of the following N (N <= 100,000) lines contains two integers h (h <= 1,000,000,000) and w (w <= 1,000,000,000) which means the height and width of Alice's card, then the following N lines means that of Bob's.
Output For each test case, output an answer using one line which contains just one number.
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 Source

問題簡述

Alice和Bob各有n個矩形,Alice的矩形覆蓋多少Bob的矩形。矩形是由高度h和寬度w給出的。

問題分析

這個問題被歸類為貪心,其實就是個排序匹配問題。數一下Alice的矩形覆蓋多少Bob的矩形,要儘可能地多。

這需要一個一個去試探,每次儘量匹配儘可能大並且最為接近的矩形。

矩形按照高度和寬度分別排序。

先匹配高度,再匹配寬度。

程式說明

矩形用pair型別表示,對於排序來說是方便的,程式碼比較簡潔。

集合類multiset不同於set,允許元素重複。同時需要注意的是,集合中的元素已經從小到大排過序。

函式(方法)upper_bound的用法也需要事先掌握。

題記:(略)

參考連結

:(略)

AC的C++語言程式如下:

/* HDU4268 Alice and Bob */

#include <iostream>
#include <algorithm>
#include <set>
#include <stdio.h>

using namespace std;

const int N = 1e5;

typedef pair<int, int> rect;
rect a[N], b[N];

int main()
{
    int t, n;

    scanf("%d", &t);
    while(t--) {
        multiset<int> s;

        scanf("%d", &n);
        for(int i=0; i<n; i++)
            scanf("%d%d", &a[i].first, &a[i].second);
        for(int i=0; i<n; i++)
            scanf("%d%d", &b[i].first, &b[i].second);

        sort(a, a + n);
        sort(b, b + n);

        int ans = 0;
        for(int i=0, j=0; i<n; i++) {
            while(j<n && a[i].first >= b[j].first) {
                s.insert(b[j].second);
                j++;
            }

            set<int>::iterator iter = s.upper_bound(a[i].second);
            if(s.size() > 0 && iter != s.begin())
                iter--;
            if(s.size() > 0 && *iter <= a[i].second) {
                ans++;
                s.erase(iter);
            }
        }

        printf("%d\n", ans);
    }

    return 0;
}