PKU 1113 wall(凸包)

 

http://acm.pku.edu.cn/JudgeOnline/problem?id=1113

 

题目大意:一个国王想把自己的城堡边缘给围起来,并且呢,在城堡的外围还要再建一个圆栅栏把城堡围里面,现在就是要你求怎么样围才最省。

 

解题思路:凸包问题,求出凸包的边缘长度,再加上圆的周长就是所得了。

 

注:这道题,我在POJ过不了,始终是WA,上其他的OJ用以下代码就可以过,不懂是怎么搞的。

 

#include <iostream> #include <cmath> #include <algorithm> #define Max 1005 #define eps 1e-8 #define PI 3.141592654 using namespace std; struct point { double x; double y; double cross; }; point stack[Max];//储存凸包边缘顶点 point points[Max]; int NumOfVertex;//顶点数 int size;//stack长度 double r; double sum;//边缘长度 bool cmpyx(point a,point b)//按照yx坐标排序 { if(a.y==b.y) return a.x<b.x; return a.y<b.y; } bool cmpcross(point a,point b)//按照角度大小排序 { if(a.cross == b.cross) return a.x<b.x; return a.cross<b.cross; } bool judge(point first,point second,point third)//判断是否往右拐 { double x1,x2,y1,y2,result; x1 = second.x-first.x; x2 = third.x-first.x; y1 = second.y-first.y; y2 = third.y-first.y; result = x1*y2-y1*x2; if(fabs(result)<eps) result = 0; if(result<=0)//往右拐 return true; return false; } void Cross()//计算极角 { int i; double x,y; for(i=1;i<NumOfVertex;i++) { x = (points[i].x-points[0].x); y = (points[i].y-points[0].y); points[i].cross = acos((x/(sqrt(x*x+y*y)))); } } void Graham()//找出凸包顶点 { int top=0,i; sort(points,points+NumOfVertex,cmpyx); Cross(); sort(points+1,points+NumOfVertex,cmpcross); stack[0] = points[0]; size = 1; for (i=1;i<NumOfVertex;i++) { while (size>1&&judge(stack[top-1],stack[top],points[i])) { size--; top--; } stack[++top] = points[i]; size++; } } double caculate(point top, point top2)//计算凸包长度 { double x = (top.x - top2.x) * (top.x - top2.x); double y = (top.y - top2.y) * (top.y - top2.y); return sqrt(x + y); } int main() { int i; while (scanf("%d%lf",&NumOfVertex,&r)!=EOF) { for(i=0;i<NumOfVertex;i++) scanf("%lf%lf",&points[i].x,&points[i].y); Graham(); sum = 0; for (i=0;i<size-1;i++) sum+=caculate(stack[i],stack[i+1]); sum+=caculate(stack[0],stack[size-1]); sum+=2*PI*r; printf("%.0lf/n",sum); } return 0; }

你可能感兴趣的:(PKU 1113 wall(凸包))