在一个平面上,如果有两个点(x,y),(a,b),如果说(x,y)支配了(a,b),这是指x>=a,y>=b;用图形来看就是(a,b)坐落在以(x,y)为右上角的一个无限的区域内。
做题思路(错解):考试拿到这道题时,感觉非常熟悉,因为之前在OpenJudge上做过这道题,然而因为做题的时间离现在有点久,再加上当时做这道题时做得有点复杂,所以在想题时思路比较局限,想了一种比较复杂的解法,但最后因为小的细节导致错误。
解题思路(正解):根据题意,极大点即为在自己右上方(包括正右和正上方)没有其它点的点,最简单的思路就是直接暴力枚举每个点,判断它的右上方是否有其它点,如果没有则该点即为极大点,这种算法的时间复杂度为O(n^2),对于n=100000的数据显然会超时。
其实根据极大点的定义和样例解释的图,我们不难发现在x由小到大有序排列时,极大点的y是严格递减的,所以我们可以先将输入的点按x由小到大排序(x相等时,按y由小到大排序),因为x最大且y最大的点(即排序后的最后一个点)一定是极大点,所以可以从第N个点开始倒着枚举每个点,设maxy来记录当前极大点中y的最大值,当第i个点的y大于maxy时,该点就是极大点。对于极大点的记录可以用vis数组进行标记,或者将极大点存在一个结构体中,找完极大点后将该结构体按题目要求的顺序排序,然后输出即可,此算法的时间复杂度为O(n)。
#include
#include
#include
#include
#include
using namespace std;
const int maxn=100005;
int N;
struct data
{
int x,y;
};
data a[maxn],ans[maxn];
bool cmp1(data aa,data bb)
{
if(aa.x!=bb.x) return aa.x=0;i--)
{
if(a[i].y>maxy) //严格递增
{
cnt++;
ans[cnt].x=a[i].x,ans[cnt].y=a[i].y;
maxy=a[i].y;
}
}
sort(ans+1,ans+1+cnt,cmp1);
printf("(%d,%d)",ans[1].x,ans[1].y); //注意输出是不能多输','
for(int i=2;i<=cnt;i++)
printf(",(%d,%d)",ans[i].x,ans[i].y);
return 0;
}