http://acm.hdu.edu.cn/showproblem.php?pid=1348
这题是在求凸包的基础上,再求每个顶点对应角度及半径的弧长,外面围墙的直线部分与城墙的凸包长相同;再求弧长总和,注意每段弧长对应的角与凸包顶点的夹角是一样的,所以,又因为每个顶对应的半径长都是l,所以一个多边形的所顶点对应弧长相加其实就是一个圆。
所以,最后总长为 凸包边长+2*3.141592653*l(l为已知与城堡的最远距离)
#include<stdio.h> #include<math.h> #define PI 3.141592653 struct node { double x,y; }p[11000]; int hash[11000]; double distance(int a,int b)//求两点之间距离 { return sqrt(pow(p[a].x-p[b].x,2)+pow(p[a].y-p[b].y,2)); } int cross_product(int a,int b,int c)//求两向量叉乘 { double x1,y1,x2,y2; x1=p[a].x-p[c].x; y1=p[a].y-p[c].y; x2=p[b].x-p[c].x; y2=p[b].y-p[c].y; if(x1*y2-x2*y1>0) return a; if(fabs(x1*y2-x2*y1)<1e-6) { if(distance(a,c)>distance(b,c))return a; else return b; } return b; } int main() { int n,i,p0,j,pj,pi,t; double x0,y0,sum,l; scanf("%d",&t); while(t--) { scanf("%d%lf",&n,&l); sum=0; x0=y0=999999; for(i=0;i<n;i++) { hash[i]=0; scanf("%lf%lf",&p[i].x,&p[i].y); if(p[i].y<y0||(p[i].y==y0&&p[i].x<x0)) { x0=p[i].x; y0=p[i].y; p0=i; } } pi=p0; for(i=0;i<n;i++) { pj=p0; for(j=0;j<n;j++) { pj=cross_product(j,pj,pi); } hash[pj]=1; sum=sum+distance(pi,pj); pi=pj; if(pj==p0)break; } sum+=2.0*l*PI; sum=(sum*10+5)/10; printf("%d ",(int)sum); if(t)printf(" "); } return 0; }