【解题报告】【HDOJ1392】【Graham凸包】Surround the Trees

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392

典型凸包

1.当只有一个点时 输出时0.00

2.当只有两个点时 输出时两个点的距离

3.当n>2 且共线时,输出需要*2,(这个是题目的奇怪之处,当只有2点时不用)

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 #define max(a,b) (a>b?b:a)
  5 
  6 struct node{
  7     double x,y;
  8     int i;
  9 };
 10 
 11 struct node stack[101];
 12 long int point1,point2;
 13 double  x[101];
 14 double  y[101];
 15 
 16 void instack(int x,int y,int i);//入栈
 17 void outstack();//出栈
 18 
 19 int main()
 20 {
 21     long int n,i,j,t1;
 22     double sum,a,b,x1,x2,y1,y2,t,p;
 23     //freopen("1.txt","r",stdin);
 24     
 25     while(scanf("%ld",&n)!=EOF&&n)
 26     {
 27 
 28         t1=0;//代表着y0
 29         for(i=0;i<n;i++)
 30         {
 31             scanf("%lf%lf",&x[i],&y[i]);
 32             if((y[i]<y[t1])||(x[i]>x[t1]&&y[i]==y[t1]))//寻找Y最小的点,若同,则寻X最大
 33                 t1=i;
 34         }
 35 
 36         if(n==1) { printf("0.00\n"); continue;}//当只有一个点时
 37         if(n==2) //当只有两个点时
 38         {
 39             a=(x[1]-x[0])*(x[1]-x[0]);
 40             b=(y[1]-y[0])*(y[1]-y[0]);
 41             printf("%.2lf\n",sqrt(a+b));
 42             continue;
 43         }
 44 
 45         //将y0点放在x[0],y[0];
 46                 p=x[t1];
 47                 x[t1]=x[0];
 48                 x[0]=p;
 49                 p=y[t1];
 50                 y[t1]=y[0];
 51                 y[0]=p;    
 52         
 53         //将x[0],y[0]作为标准
 54         for(i=1;i<n;i++)
 55         {
 56             x[i]=x[i]-x[0];
 57             y[i]=y[i]-y[0];
 58         }
 59         x[0]=0;y[0]=0;
 60     
 61         //按角度从小到大排序
 62         for(i=1;i<n;i++)
 63         {
 64             for(j=i;j<n;j++)
 65                 if(x[i]*y[j]-x[j]*y[i]<0)
 66                 {
 67                     t=x[i];
 68                     x[i]=x[j];
 69                     x[j]=t;
 70                     t=y[i];
 71                     y[i]=y[j];
 72                     y[j]=t;
 73                 }
 74         }
 75 
 76         //将前三点入栈
 77         stack[0].x=x[0];stack[0].y=y[0];stack[0].i=0;
 78         stack[1].x=x[1];stack[1].y=y[1];stack[1].i=1;
 79         stack[2].x=x[2];stack[2].y=y[2];stack[2].i=2;        
 80         point1=1;
 81         point2=2;
 82         //利用拐向来判断是否凸包内的
 83         for(i=3;i<n;)
 84         {
 85             
 86             x1=x[i]-stack[point1].x;
 87             y1=y[i]-stack[point1].y;
 88             
 89             x2=stack[point2].x-stack[point1].x;
 90             y2=stack[point2].y-stack[point1].y;
 91             
 92             if(x1*y2-x2*y1>=0)
 93             {
 94                 outstack();
 95                 continue;
 96             }
 97             else
 98             {
 99                 instack(x[i],y[i],i);
100             }
101             i++;
102         }
103         
104         //计算路径长度
105         sum=0;
106         for(i=1;i<=point2;i++)
107         {
108             
109             a=(stack[i].x-stack[i-1].x)*(stack[i].x-stack[i-1].x);
110             b=(stack[i].y-stack[i-1].y)*(stack[i].y-stack[i-1].y);
111             sum+=sqrt(a+b);
112         }
113 
114         //输出
115         if(point2==1) printf("%.2lf\n",sum*2);//当n>2 且全部共线
116         else//正常情况的输出
117         {
118             a=stack[point2].x*stack[point2].x;
119             b=stack[point2].y*stack[point2].y;
120             sum+=sqrt(a+b);
121             printf("%.2lf\n",sum);
122         }
123         
124     }
125     return 0;
126 }
127 
128 //***********下面为子函数***************
129 void instack(int x,int y,int i)//入栈
130 {
131     point1++;
132     point2++;
133     stack[point2].x=x;
134     stack[point2].y=y;
135     stack[point2].i=i;
136 }
137 
138 void outstack()//出栈
139 {
140     point1--;
141     point2--;
142 }

 

posted on 2012-07-23 17:34  coding封神  阅读(133)  评论(0编辑  收藏  举报

导航