1855: 圈水池 凸包

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn=109;

struct node {
	int x,y;
} edge[maxn],ans[maxn];

bool cmp(node a,node b) {
	if(a.x==b.x) return a.y<b.y;
	return a.x<b.x;
}
int mul(node a,node b,node c) {
	return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
int solve(int n) {
	int len=0;
	for(int i=0; i<n; i++) { //計算上半部分
		while(len>1&&mul(ans[len-2],ans[len-1],edge[i])<=0)
			len--;
		ans[len++]=edge[i];
	}
	int k=len;
	//printf("k:%d\n",k);
	for(int i=n-1; i>=0; i--) { //計算下半部分
		while(len>k&&mul(ans[len-2],ans[len-1],edge[i])<=0)
			len--;
		ans[len++]=edge[i];
	}
	return len-1;//最後一個是開始點(開始點被記錄了兩次)
}

int main() {
	int t,n;
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		for(int i=0; i<n; i++)
			scanf("%d%d",&edge[i].x,&edge[i].y);

		sort(edge,edge+n,cmp);

		int len=solve(n);
		sort(ans,ans+len,cmp);
		for(int i=0; i<len; i++)
			printf("%d %d\n",ans[i].x,ans[i].y);
	}
	return 0;
}

時間限制: 3 Sec  內存限制: 64 MB
提交: 16  解決: 9
[提交][狀態][討論版]

題目描述

有一個牧場,牧場上有很多個供水裝置,現在牧場的主人想要用籬笆把這些供水裝置圈起來,以防止不是自己的牲畜來喝水,各個水池都標有各自的座標,現在要你寫一個程序利用最短的籬笆將這些供水裝置圈起來!(籬笆足夠多,並且長度可變)

輸入

第一行輸入的是N,代表用N組測試數據(1<=N<=10) 第二行輸入的是m,代表本組測試數據共有m個供水裝置(3<=m<=100) 接下來m行代表的是各個供水裝置的橫縱座標

輸出

輸出各個籬笆經過各個供水裝置的座標點,並且按照x軸座標值從小到大輸出,如果x軸座標值相同,再安照y軸座標值從小到大輸出

樣例輸入

1
4
0 0
1 1
2 3
3 0

樣例輸出

0 0
2 3
3 0
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章