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