NYOJ 78 圈水池(凸包问题)

 圈水池

时间限制:3000 ms  |  内存限制:65535 KB
难度:4
 
描述
有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)
 
输入
第一行输入的是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
#include<iostream>
#include<algorithm>
using namespace std;

struct point{
	int x;
	int y;
}p[105], ch[105];

bool cmp(point t1, point t2)
{
	return (t1.x < t2.x) || (t1.x == t2.x && t1.y < t2.y);
}

bool Cross(point t1,point t2,point t3)
{
	return (t1.x-t3.x)*(t1.y-t2.y) > (t1.x - t2.x)*(t1.y - t3.y);
}

int ConvexHull(point *p, int n, point *ch)
{
	int i;
	sort(p,p+n,cmp);
	int m = 0;
	for(i=0; i<n; ++i)
	{
		while(m>1 && Cross(p[i],ch[m-1],ch[m-2]))
			m--;
		ch[m++] = p[i];
	}
	int k = m;
	for(i = n-2; i >= 0; --i)
	{
		while(m > k && Cross(p[i],ch[m-1],ch[m-2]))
			m--;
		ch[m++] = p[i];
	}
	if(n>1) m--;
	return m;
}


int main()
{
	freopen("in.txt","r",stdin);
	int N,m,i;
	cin>>N;
	while(N--)
	{
		cin>>m;
		for(i=0; i<m; ++i)
			cin>>p[i].x>>p[i].y;
		int j = ConvexHull(p,m,ch);
		sort(ch,ch+j,cmp);
		for(i=0; i<j; ++i)
			cout<<ch[i].x<<" "<<ch[i].y<<endl;
	}
	return 0;
}
原文地址:https://www.cnblogs.com/yaling/p/3048098.html