例题3.19 优势人群 UVa11020

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值