資訊學奧賽一本通 1230:尋找平面上的極大點(evd)

everwide1982發表於2020-10-24

【題目描述】
在一個平面上,如果有兩個點(x,y),(a,b),如果說(x,y)支配了(a,b),這是指x≥a,y≥b;

用圖形來看就是(a,b)坐落在以(x,y)為右上角的一個無限的區域內。

給定n個點的集合,一定存在若干個點,它們不會被集合中的任何一點所支配,這些點叫做極大值點。

程式設計找出所有的極大點,按照x座標由小到大,輸出極大點的座標。

本題規定:n不超過100,並且不考慮點的座標為負數的情況。

【輸入】
輸入包括兩行,第一行是正整數n,表示是點數,第二行包含n個點的座標,座標值都是整數,座標範圍從0到100,輸入資料中不存在座標相同的點。

【輸出】
按x軸座標最小到大的順序輸出所有極大點。

輸出格式為:(x1,y1),(x2,y2),…(xk,yk)。

注意:輸出的每個點之間有",“分隔,最後一個點之後沒有”,",少輸出和多輸出都會被判錯。

【輸入樣例】
5
1 2 2 2 3 1 2 3 1 4
【輸出樣例】
(1,4),(2,3),(3,1)
【提示】在這裡插入圖片描述
【心得】理解了極大值點的含義做題就容易多了,x從大到小列舉,y值必須越來越大才不會被支配。
【AC程式碼】

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=105;
struct coord
{
	int x,y,z;
}c[maxn];
bool cmp(struct coord a,struct coord b)
{
	if(a.x==b.x) return a.y<b.y;
	return a.x<b.x;
}
bool comp(struct coord a,struct coord b)
{
	if(a.z==1&&b.z==1) return a.x<b.x;
	else return a.x<b.x;
}
int main()
{
	int n,he;
	cin>>n;
	for(int i=0;i<n;i++) 
	{
		cin>>c[i].x>>c[i].y;
		c[i].z=0;
	}
	sort(c,c+n,cmp);
	c[n-1].z=1;//最後一個肯定是極大值點
	he=c[n-1].y;
	for(int i=n-2;i>=0;i--)
	{
		if(c[i].y>he)//x越小,y應該越大
		{
			he=c[i].y;
			c[i].z=1;
		}
	}
	sort(c,c+n,comp);//x從小到達輸出
	bool first=true;
	for(int i=0;i<n;i++)
	{
		if(c[i].z)
		{
			if(first) 
			{
				printf("(%d,%d)",c[i].x,c[i].y);
				first=false;
			}
			else printf(",(%d,%d)",c[i].x,c[i].y);
		}	
	}
	return 0;
}

相關文章