zoukankan      html  css  js  c++  java
  • Alice and Bob hdu 4268

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4268

    题意:

    Alice 和 Bob 都有n张牌,分别有长和宽

    存在一种覆盖操作:a牌可以覆盖b牌的条件为,b的长和宽必须均小于a

    覆盖操作中不允许牌进行旋转。

    问Alice手中的牌最多可以覆盖Bob手中多少张牌?   注:覆盖成功的两张牌均被弃置。

    思路:

    首先肯定要把两人手中的牌按先长后宽从小到大排个序。

    第一次尝试(超时)

    刚开始的时候用multiset分别存了两个人的牌,然后从Alice开始遍历找Bob的牌,如果A牌的长宽均小于B牌时A立即换牌,不再遍历B牌(一定要遍历B的,不能只判断第一张牌,如果当前A为(4,5),B为(3,8),不能覆盖,但是B的下一张可能为(4,4),还是可以覆盖的,所以必须遍历)。

    但是,即使加了这样简单的剪枝,还是 TLE。

    第二次尝试(超内存)

    经过第一次,发现怎么都要遍历两次,后来找到了一种方法,第一次遍历O(n),第二次用二分去找O(logN),这就快多了。

    从Alice开始遍历,把B中所有长度小于等于当前A牌的Bob的牌均置于multiset中,然后找一个长度不大于当前A的牌,然后删掉,计一次数,用二分查找upper_bound。

    时间是变成O(N log N)了,但是这个时候内存又超了,(??),难道multiset还超内存,后来把Alice和Bob的存储改成了vector,心想这下总不会超内存了吧,但结果还是超内存。

    第三次

    实属无奈,只好把Alice和Bob的存储全都换成数组,然后就过了。。。。。。

    代码如下:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<set>
     4 #include<algorithm>
     5 using namespace std;
     6 class Card
     7 {
     8 public:
     9     int _h, _w;
    10     bool operator<(const Card& rhs)const
    11     {
    12         return _h < rhs._h;
    13     }
    14 };
    15 Card A[100001], B[100001];
    16 multiset<int>C;
    17 
    18 int main()
    19 {
    20     int group, cardnum;
    21     scanf("%d", &group);
    22     while (group--)
    23     {
    24         C.clear();
    25         scanf("%d", &cardnum);
    26         int result = 0;
    27         for (int i = 0; i < cardnum; ++i)
    28             scanf("%d%d", &A[i]._h, &A[i]._w);
    29         for (int i = 0; i < cardnum; ++i)
    30             scanf("%d%d", &B[i]._h, &B[i]._w);
    31         sort(A, A + cardnum);
    32         sort(B, B + cardnum);
    33         for (int i = 0, j = 0; i < cardnum; ++i)
    34         {
    35             while (j < cardnum && A[i]._h >= B[j]._h)
    36             {
    37                 C.insert(B[j]._w);
    38                 ++j;
    39             }
    40             if (!C.empty() && A[i]._w >= *C.begin())
    41             {
    42                 multiset<int>::iterator t = C.upper_bound(A[i]._w);
    43                 t--;
    44                 result++;
    45                 C.erase(t);
    46             }
    47         }
    48         printf("%d
    ", result);
    49     }
    50 }

    感谢您的阅读,生活愉快~

  • 相关阅读:
    JVM 关于对象分配在堆、栈、TLAB的理解
    分布式唯一 ID 生成方案有哪些?
    JVM 栈帧之操作数栈与局部变量表 转
    C# TreeHelper帮助类
    Java:Top K问题的解法
    C#单例模式
    C#分组方式比较
    Vue实现登录
    git使用总结
    js实现无色彩球
  • 原文地址:https://www.cnblogs.com/lv-anchoret/p/8474032.html
Copyright © 2011-2022 走看看