圈水池
时间限制:
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
-
-
第一行输入的是N,代表用N组测试数据(1<=N<=10)
-
坐标为整数
-
ac代码:
-
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #define fab(a) (a)>0?(a):(-a) #define LL long long #define MAXN 55000 #define mem(x) memset(x,0,sizeof(x)) #define INF 0xfffffff #define PI acos(-1.0) using namespace std; struct s { int x,y; }list[MAXN],a[MAXN]; int stack[MAXN],top; double dis(s aa,s bb) { return sqrt((aa.x-bb.x)*(aa.x-bb.x)+(aa.y-bb.y)*(aa.y-bb.y)); } int cross(s p0,s p1,s p2) { return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x); } bool cmp(s aa,s bb) { int num=cross(list[0],aa,bb); if(num>0) return true; else if(num==0&&dis(list[0],aa)<dis(list[0],bb)) return true; else return false; } bool cmp1(s aa,s bb) { if(aa.x==bb.x) return aa.y<bb.y; return aa.x<bb.x; } void graham(int n) { int i; if(n==1) {top=0;stack[0]=0;} if(n==2) {top=1;stack[0]=0;stack[1]=1;} if(n>2) { for(i=0;i<2;i++) stack[i]=i; top=1; for(i=2;i<n;i++) { while(top>0&&cross(list[stack[top-1]],list[stack[top]],list[i])<=0) top--; top++; stack[top]=i; } } } int main() { int n,r,i,t; scanf("%d",&t); while(t--) { scanf("%d",&n); s low; scanf("%d%d",&list[0].x,&list[0].y); low.x=list[0].x,low.y=list[0].y; int k=0; for(i=1;i<n;i++) { scanf("%d%d",&list[i].x,&list[i].y); if(((low.x==list[i].x)&&(low.y>list[i].y))||low.x>list[i].x) { low.x=list[i].x; low.y=list[i].y; k=i; } } list[k]=list[0]; list[0]=low; sort(list+1,list+n,cmp); graham(n); int q=0; for(i=0;i<=top;i++)//路径点存入新数组,然后排序 { a[q++]=list[stack[i]]; } sort(a,a+q,cmp1); for(i=0;i<q;i++) printf("%d %d\n",a[i].x,a[i].y); } return 0; }
-