凸包问题(圈水池)

凸包问题

http://acm.nyist.net/JudgeOnline/problem.php?pid=3

问题描述:

有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)

输入:

第一行输入的是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>
#define N 105
using namespace std;
struct point
{
	int x,y;
}p[N],ret[N];

bool camp(point p1,point p2)
{
	return p1.x<p2.x||p1.x==p2.x&&p1.y<p2.y;
}
 
bool milti(point p0,point p1,point p2)
{
	return (p1.x-p0.x)*(p2.y-p0.y)>(p2.x-p0.x)*(p1.y-p0.y);
}
int graham(point p[],int n,point ret[])
{
	int i ,len,top=1;
	sort(p,p+n,camp);
	if(n==0)return 0;ret[0]=p[0];
	if(n==1)return 1;ret[1]=p[1];
	if(n==2)return 2;ret[2]=p[2];
 
	for(  i=2;i<n;i++)
	{
	while(top&&milti(p[i],ret[top],ret[top-1]))
	top--;
	ret[++top]=p[i];	
	}
	len=top;
	ret[++top]=p[n-2];
	for(i=n-3;i>=0;i--)
	{
		while(top!=len&&milti(p[i],ret[top],ret[top-1]))
		top--;
		ret[++top]=p[i];
	}
	return top;
}
int main(int argc, char *argv[])
{
	int t,i,cas,k;
	cin>>cas;
	while(cas--)
	{
	cin>>t;
	for(i=0;i<t;i++)
	cin>>p[i].x>>p[i].y;
	k=graham(p,t,ret);
	sort(ret,ret+k,camp);
	for(i=0;i<k;i++)
	cout<<ret[i].x<<" "<<ret[i].y<<endl;
		
	}
	return 0;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值