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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-12 18:09:33