一个水题
一种比较简单的思路:贪心
我们可以对于每一个点根据x从小到大排好序
这样对于每一个点,只需要不存在序列中在它后面并且纵坐标大于它的点
那么我们当前枚举的这个点就是满足题意的点
但显然,从小到大枚举并查询后面是否有纵坐标大于该点的点相对会复杂一些
我们可以考虑倒序来枚举
记录下当前枚举到点中纵坐标的最大值,这样每枚举到的点只需要与最大值比较即可
如果它大于最大值,即为符合题意的点
但这种贪心策略只能得到90分
为什么?
我们按照x又小到大排序的时候忽略了x相等,也就是在一列的点的情况
只需要先按照x排序,x相等再按照y排序就行了
code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<bits/stdc++.h>
using namespace std;
int read(){
int a = 0,f = 0;char p = getchar();
while(!isdigit(p)){f|=p=='-';p = getchar();}
while(isdigit(p)){a = (a << 3) + (a << 1) + (p^48);p = getchar();}
return f?-a:a;
}
int n;
struct node{
int x,y,bh;
}point[500001];
//int tot[500001];
//bool flag[500001];
bool cmp1(node a,node b){
if(a.x!=b.x){
return a.x < b.x;
}
return a.y < b.y;
}
int ansx[500001],ansy[500001];
void _Solve(){
sort(point+1,point+n+1,cmp1);
int now = 0,num = 0;
for(int i = n;i >= 1;i--){
if(point[i].y > now){
ansx[++num] = point[i].x;
ansy[num] = point[i].y;
now = point[i].y;
}
}
for(int i = num;i >= 2;i--){
cout <<"("<< ansx[i] <<","<< ansy[i]<<")"<<",";
}
cout<<"("<<ansx[1]<<","<<ansy[1]<<")";
}
int main(){
n = read();
for(int i = 1;i <= n;i ++){
point[i].x = read();
point[i].y = read();
point[i].bh = i;
}
_Solve();
}
啊好了没了就写了这么多qwq