您的位置:首页 > 其它

HDU4268 Alice and Bob

2012-09-17 18:40 405 查看
  原题传送:http://acm.hdu.edu.cn/showproblem.php?pid=4268

  贪心算法。

  对a、b数组进行二维排序(先按长h从小到大排序,相同的h按宽w从小到大排序),对于b的h小于a的h,把b的w添加到集合中,并从集合里面选择一个可以覆盖的最大的w即可(因为此时由于第一维h已经满足覆盖条件,只需要考虑第二维的w)。

  这道题在比赛的时候没做出来,后来看了解题报告,才发现STL神器之multiset,这就是比赛时苦苦寻找的数据结构啊!这东西自己从来没用过的,此刻必须记录下它的两个重要特点:

  1.它有优先队列的性质,插入的元素是有序的,插入复杂度和priority_queue一样只有O(log(n));

  2.它有两个很好用的方法:

    a.lower_bound(key):返回指向第一个">=key"的元素的迭代指针;

    b.upper_bound(key):返回指向第一个">key"的元素的迭代指针;

  (这两个方法都是O(log(n))复杂度,很高效),并且删除操作也很容易。

View Code

#include <stdio.h>
#include <set>
#include <algorithm>
#define N 100001
using namespace std;

struct node
{
int h, w;
}a
, b
;

multiset<int> s;

bool cmp(node x, node y)
{
if(x.h < y.h)
return true;
else if(x.h == y.h)
return x.w < y.w ? true : false;
else
return false;
}

int main()
{
int n, i, j, cas, cnt;
scanf("%d", &cas);
while(cas --)
{
s.clear();
scanf("%d", &n);
for(i = 0; i < n; i ++)
scanf("%d%d", &a[i].h, &a[i].w);
for(i = 0; i < n; i ++)
scanf("%d%d", &b[i].h, &b[i].w);
sort(a, a + n, cmp);
sort(b, b + n, cmp);
for(cnt = i = j = 0; i < n; i++)
{
while(j < n && b[j].h <= a[i].h)
{
s.insert(b[j].w);
j ++;
}
if(!s.empty() && *s.begin() <= a[i].w)
{
multiset <int>::iterator it = s.upper_bound(a[i].w);
cnt ++;
it --;
s.erase(it);
}
}
printf("%d\n", cnt);
}
return 0;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: