POJ 1113 Wall (凸包)

凸包基础题,求凸包周长。最后加上一个半径为L的圆即可。不理解的话算一下多边形内角和。

//Memory: 236 KB		
//Time: 63 MS
#include <iostream>
#include <math.h>
#include <algorithm>
#include <stdio.h>
#define PI 3.14159265
using namespace std;
int top;
struct POINT
{
	double x,y;
};POINT PointSet[1005];POINT ch[1005];
double multiply(POINT sp,POINT ep,POINT op) 
{ 
	return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y)); 
}
double dist(POINT p1,POINT p2)              
{ 
	return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) ); 
}
bool ptcmp(POINT a,POINT b) 
{
   if ( multiply(a,b,PointSet[0])>0 ||  // 极角更小    
		(multiply(a,b,PointSet[0])==0) &&	/* 极角相等,距离更短 */        
		dist(PointSet[0],a)<dist(PointSet[0],b))
		return 1;
   return 0;
}
void Graham_scan(int n) 
{ 
	int i,k=0;
	top=2; 
	POINT tmp; 
	// 选取PointSet中y坐标最小的点PointSet[k],如果这样的点有多个,则取最左边的一个 
	for(i=1;i<n;i++) 
		if ( PointSet[i].y<PointSet[k].y || (PointSet[i].y==PointSet[k].y) && (PointSet[i].x<PointSet[k].x) ) 
			k=i; 
	tmp=PointSet[0]; 
	PointSet[0]=PointSet[k]; 
	PointSet[k]=tmp;		// 现在PointSet中y坐标最小的点在PointSet[0] 
	sort(PointSet+1,PointSet+n,ptcmp);	//sort排序
	ch[0]=PointSet[0]; 
	ch[1]=PointSet[1]; 
	ch[2]=PointSet[2]; 
	for (i=3;i<n;i++) 
	{ 
		while (multiply(PointSet[i],ch[top],ch[top-1])>=0) 
			top--; 
		ch[++top]=PointSet[i]; 
	}
	ch[++top]=ch[0];
} 
int main()
{
	int n,l;
	while(cin>>n>>l)
	{
		int i;
		double line=0;
		for(i=0;i<n;i++)
			cin>>PointSet[i].x>>PointSet[i].y;
		Graham_scan(n);
		for(i=0;i<top;i++)
		{
			line+=dist(ch[i],ch[i+1]);
		}
		line+=2*l*PI;
		printf("%.0lf\n",line);
	}
	return 0;
}


你可能感兴趣的:(ini)