您的位置:首页 > 其它

nyoj 圈水池 78 (二维凸包 数学几何) 凸包入门

2015-10-30 18:01 162 查看

圈水池

时间限制: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<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct zz
{
int x;
int y;
friend int operator<(zz a,zz b)
{
if((a.x<b.x)||(a.x==b.x&&a.y<b.y))
return 1;
return 0;
}
}a[110],ans[110];
double judge(zz a,zz b,zz c)//判断条件
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
int main()
{
int T,n,m;
int i,j;
scanf("%d",&T);
while(T--)
{
scanf("%d",&m);
for(i=0;i<m;i++)
scanf("%d%d",&a[i].x,&a[i].y);
sort(a,a+m);
int k1=0;
for(i=0;i<m;i++)//下凸包
{
while(k1>1&&judge(ans[k1-2],ans[k1-1],a[i])<=0)
k1--;
ans[k1++]=a[i];
}
int k2=k1;
for(i=m-1;i>=0;i--)//上凸包
{
while(k1>k2&&judge(ans[k1-2],ans[k1-1],a[i])<=0)
k1--;
ans[k1++]=a[i];
}
k1--;
sort(ans,ans+k1);//按从小到大排序
for(i=0;i<k1;i++)
printf("%d %d\n",ans[i].x,ans[i].y);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: