码迷,mamicode.com
首页 > 其他好文 > 详细

例题3.19 优势人群 UVa11020

时间:2015-08-30 23:11:19      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

1.题目描述:点击打开链接

2.解题思路:本题利用multiset解决。根据题意,如果我们用P(x,y)表示一个人,因为人可以相同,所以用multiset。我们会发现,如果所有人群都是有优势的,那么这些点呈现一个递减的趋势。如果刚刚插入一个人,他是否有优势该如何判断呢?只需要看他左边相邻的点的y坐标是否比他小即可。而如果这个人是有优势的,那么需要先把这个人插入到集合中,然后从upper_bound(P)开始,逐个删除没有优势的点,注意删除时候应写为s.erase(it++),因为删除时候会导致指针向左移动一位,因此还需要it++。这样,此时S.size()就是答案。

3.代码:

#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;

#define me(s)  memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
//typedef pair <int, int> P;


struct Point
{
    int a,b;
    bool operator<(const Point&rhs)const
    {
        return a<rhs.a||(a==rhs.a&&b<rhs.b);
    }
};

multiset<Point>S;
multiset<Point>::iterator it;

int main() 
{
  int T;
  scanf("%d", &T);
  for(int kase = 1; kase <= T; kase++) 
    {
    if(kase > 1) printf("\n");
    printf("Case #%d:\n", kase);

    int n, a, b;
    scanf("%d", &n);
    S.clear();
    while(n--) 
    {
      scanf("%d%d", &a, &b);
      Point P = (Point){a, b};
      it = S.lower_bound(P);//先找到这个人的位置
      if(it == S.begin() || (--it)->b > b) //如果他左边没人 或 他左边的人y值大于b,说明此人是有优势的,应该加入集合
      {
        S.insert(P);
        it = S.upper_bound(P);
        while(it != S.end() && it->b >= b) S.erase(it++);
      }
      printf("%d\n", S.size());
    }
  }
  return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

例题3.19 优势人群 UVa11020

标签:

原文地址:http://blog.csdn.net/u014800748/article/details/48110265

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!