Day3-H-Alice and Bob HDU4268

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. 

InputThe 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. 
OutputFor 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

思路:依旧是贪心,但这个是二维问题,我们可以类比二位偏序问题来处理,先对h排序,扫描一遍Alice的数组,将每个小于等于h的Bob的元素入队,然后将小于等于w的元素出队
记录个数,此时无需关心h,因为入队的元素一定不大于现在的h,这里我们就要用到multiset这个容器来"当作队列",因为其支持upper_bound/lower_bound的二分查找操作,
具体细节用代码感受一下:
struct Node {
    int h, w;
    Node(int _h = 0, int _w = 0) : h(_h), w(_w){}
    bool operator<(const Node &a)const {
        return h < a.h || (h == a.h && w < a.w);
    }
};

vector<Node> v[2];
multiset<int> q;

int main() {
    int T, n, sum;
    scanf("%d", &T);
    while(T--) {
        q.clear();
        sum = 0;
        scanf("%d", &n);
        for (int i = 0; i < 2; ++i) {
            v[i].clear();
            for (int j = 0; j < n; ++j) {
                int t1, t2;
                scanf("%d%d", &t1, &t2);
                v[i].push_back(Node(t1, t2));
            }
        }
        sort(v[0].begin(), v[0].end()), sort(v[1].begin(), v[1].end());
        for (int i = 0, j = 0; i < n; ++i) {
            while(j < n && v[0][i].h >= v[1][j].h) {
                q.insert(v[1][j++].w);
            }
            if(!q.empty() && *q.begin() <= v[0][i].w) {
                ++sum;
                auto tmp = q.upper_bound(v[0][i].w);
                q.erase(--tmp);
            }
        }
        printf("%d\n", sum);
    }
    return 0;
}
View Code
 
 

 提一下为什么用upper_bound并递减,因为当此处的w比队列中任意元素大时,两种查找都返回end()迭代器,此时需要递减操作,如果w是中间大小元素,lower_bound的递减就会出错,当然特判一下也可以,等价的。

 

转载于:https://www.cnblogs.com/GRedComeT/p/11241574.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值