ZOJ 1465 Wall

看图片就知道了,一个凸包加一个半径为L的圆的周长

即使不是长方形的凸包,道理也是一样的,围墙总是会和多边形的凸包平行的,长度也就相等,在转角的地方才会有弧形,而所有的弧形加到一起一定是一个圆,多边形外角和是360度嘛。

#include<stdio.h>
#include<math.h>
#include<algorithm>
#define pi 3.14159265358979323
#define eps 1e-10
#define X 1010
using namespace std;
struct point{
	double x,y;
}c[X],stk[X];
int n,top;
inline bool dy(double x,double y){return x>y+eps;}
inline bool xy(double x,double y){return x<y-eps;}
inline bool dyd(double x,double y){return x>y-eps;}
inline bool xyd(double x,double y){return x<y+eps;}
inline bool dd(double x,double y){return fabs(x-y)<eps;}
inline double cp(point a,point b,point c){
	return (c.x-a.x)*(b.y-a.y)-(c.y-a.y)*(b.x-a.x);
}
inline double disp2p(point a,point b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline bool cmp(point a,point b){
	double len=cp(c[0],a,b);
	if(dd(len,0.0)) return xy(disp2p(c[0],a),disp2p(c[0],b));
	return xy(len,0.0);
}
void graham(){
	int i,tmp=0;
	for(i=1;i<n;i++)
	    if(xy(c[i].x,c[tmp].x)||dd(c[i].x,c[tmp].x)&&xy(c[i].y,c[tmp].y))
	        tmp=i;
	 swap(c[0],c[tmp]);
	 sort(c+1,c+n,cmp);
	 stk[0]=c[0];stk[1]=c[1];
	 top=1;
	 for(i=2;i<n;i++){
		while(xy(cp(stk[top],stk[top-1],c[i]),0.0)&&top>=1)
		    top--;
		stk[++top]=c[i];
	}
	stk[++top]=c[0];
}
int main(){
	int i,t;
	double l,sum;
	scanf("%d",&t);
	while(t--){
		scanf("%d%lf\n",&n,&l);
		for(i=0;i<n;i++)
		    scanf("%lf%lf",&c[i].x,&c[i].y);
		graham();
		sum=0;
		for(i=0;i<top;i++)
		    sum+=disp2p(stk[i],stk[i+1]);
		sum+=2*pi*l;
		printf("%.0lf\n",sum);
		if(t)
		    printf("\n");
	}
	return 0;
}

 


 

你可能感兴趣的:(c,ini,360)