zoukankan      html  css  js  c++  java
  • 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
    ", sum);
        }
        return 0;
    }
    View Code
    
    

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

     
  • 相关阅读:
    linux操作系统及内核
    2.1.1Remove Duplicates from Sorted Arr
    顺序表
    开博篇
    ssh无法root用户登录与登录界面无法选择用户登录
    Ubuntu 18.04 Server安装GUI桌面
    Linux 命令 su 和 sudo 区别
    坑(二十六)—— mysql出现ERROR1698(28000):Access denied for user root@localhost错误解决方法
    redhat安装wps
    gitlab重置root密码
  • 原文地址:https://www.cnblogs.com/GRedComeT/p/11241574.html
Copyright © 2011-2022 走看看