【解题报告】【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 }