圈水池

时间限制: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
原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=78
典型的凸包问题,直接上代码
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 typedef struct
 4 {
 5     int x,y;
 6 } point;
 7 point pnt[100],res[100];
 8 bool mult(point sp,point ep,point op)
 9 {
10     return (sp.x-op.x)*(ep.y-op.y)>=(ep.x-op.x)*(sp.y-op.y);
11 }
12 int camp(const void *a,const void*b)
13 {
14     point *p1=(point*)a,*p2=(point*)b;
15     if(p1->x==p2->x) return p1->y>p2->y;
16     else return p1->x>p2->x;
17 }
18 int graham(int n)
19 {
20     int i,len,top=1;
21     if(n==0) return 0;
22     res[0]=pnt[0];
23     if(n==1) return 1;
24     res[1]=pnt[1];
25     if(n==2) return 2;
26     for(i=2;i<n;i++)
27     {
28         while(top&&mult(pnt[i],res[top],res[top-1])) top--;
29         res[++top]=pnt[i];
30     }
31     len=top;
32     res[++top]=pnt[n-2];
33     for(i=n-3;i>=0;i--)
34     {
35         while(top!=len&&mult(pnt[i],res[top],res[top-1])) top--;
36         res[++top]=pnt[i];
37     }
38     return top;
39 }
40 int main()
41 {
42     int m,n,i;
43     scanf("%d",&m);
44     while(m--)
45     {
46         scanf("%d",&n);
47         for(i=0;i<n;i++)
48         {
49             scanf("%d%d",&pnt[i].x,&pnt[i].y);
50         }
51         qsort(pnt,n,sizeof(point),camp);
52         n=graham(n);
53         qsort(res,n,sizeof(point),camp);
54         for(i=0;i<n;i++)
55         {
56             printf("%d %d\n",res[i].x,res[i].y);
57         }
58     }
59     return 0;
60 }

 

posted @ 2013-04-25 15:51  林海的博客  阅读(347)  评论(0编辑  收藏  举报