圈水池
时间限制:3000 ms | 内存限制:65535 KB
难度:4
- 描述
- 有一个牧场,牧场上有很多个供水装置,现在牧场的主人想要用篱笆把这些供水装置圈起来,以防止不是自己的牲畜来喝水,各个水池都标有各自的坐标,现在要你写一个程序利用最短的篱笆将这些供水装置圈起来!(篱笆足够多,并且长度可变)
- 输入
- 第一行输入的是N,代表用N组测试数据(1<=N<=10)
第二行输入的是m,代表本组测试数据共有m个供水装置(3<=m<=100)
接下来m行代表的是各个供水装置的横纵坐标 - 输出
- 输出各个篱笆经过各个供水装置的坐标点,并且按照x轴坐标值从小到大输出,如果x轴坐标值相同,再安照y轴坐标值从小到大输出
- 样例输入
1
0 0
1 1
2 3
3 0
- 样例输出
0 0
2 3
3 0
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
/*
PointSet[]: 输入的点集
ch[]:输出的凸包的点集,按照逆序输出
n:PointSet中点的数目
len:输出的凸包上的点的个数
*/
struct Point{
float x,y;
};
//小于说明向量p0p1的极角大于p0p2的极角
float multiply(Point p1,Point p2,Point p0)
{
return ((p1.x-p0.x)*(p2.y-p0.y) -(p2.x-p0.x)*(p1.y-p0.y));
}
float dis(Point p1,Point p2)
{
return sqrt((p1.x-p2.x)*(p1.x -p2.x) + (p1.y-p2.y)*(p1.y-p2.y));
}
void Graham_scan(Point PointSet[],Point ch[],int n,int &len)
{
int i,j,k=0,top = 2;
Point tmp;
for (i=1;i<n;i++)
if ((PointSet[i].y<PointSet[k].y ||((PointSet[i].y==PointSet[k].y)) &&(PointSet[i].x <PointSet[k].x)))
k=i;
tmp =PointSet[0];
PointSet[0]=PointSet[k];
PointSet[k]=tmp;
//按极角大小排序
for (i=1;i<n-1;i++)
{
k=i;
for (j=i+1;j<n;j++)
{
if ((multiply(PointSet[j],PointSet[k],PointSet[0])>0)
||((multiply(PointSet[j],PointSet[k],PointSet[0])==0)
&& (dis(PointSet[0],PointSet[j]) < dis(PointSet[0],PointSet[k]))))
{
tmp = PointSet[j];
PointSet[j] = PointSet[k];
PointSet[k] = tmp;
}
}
}
ch[0] = PointSet[0];
ch[1] = PointSet[1];
ch[2] = PointSet[2];
for (i=3;i<n;i++)
{
while (multiply(PointSet[i],ch[top],ch[top-1])>0)
top--;
ch[++top] = PointSet[i];
}
len = top+1;
}
const int maxN = 1000;
Point PointSet[maxN];
Point ch[maxN];
int n;
int len;
int cmp(const void *a,const void *b)
{
Point pa = *(Point *)a;
Point pb = *(Point *)b;
if (pa.x>pb.x)
return 1;
else if((pa.x ==pb.x) &&pa.y>pb.y)
return 1;
else return -1;
}
void solve()
{
int n,i;
cin>>n;
for (i=0;i<n;i++)
cin>>PointSet[i].x>>PointSet[i].y;
Graham_scan(PointSet,ch,n,len);
qsort(ch,len,sizeof(ch[0]),cmp);
for (i=0;i<len;i++)
cout<<ch[i].x<<" "<<ch[i].y<<endl;
}
int main()
{
int n;
cin>>n;
while (n--)
{
solve();
}
}