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; }