Wall--POJ 1113
1、题目类型:凸包。
2、解题思路:(1)建立点集map[][];(2)Graham法求解凸包,中间对于斜率的排序用的是STL的sort();(3)求解凸包边长的和加上以L为周长的园的周长。
3、注意事项:凸包处理过程中,Graham(),用于记录的结构体数组的开始与结束。
4、实现方法:
#include<iostream>
#include<algorithm>
#include<cmath>
#define PI 3.1415926
using namespace std;
struct Point
{
int x,y;
};
int n,L;
Point map[1010];
Point S[1010];
//求斜率
float XieLv(Point p1,Point p2,Point p0)
{
return ((p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y));
}
//两点距离
double Dis(Point p1,Point p2)
{
double distance=sqrt((double)(p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
return distance;
}
int cmp(Point p1,Point p2)
{
if(XieLv(p1,p2,map[0])>0)
return 1;
if((XieLv(p1,p2,map[0])==0&&
Dis(p1,map[0])-Dis(p2,map[0])<0))
return 1;
return 0;
}
//Graham法求凸包,返回凸包中点数
int Graham()
{
int i,top,tmp=0;
for(i=1;i<n;i++)
{
if((map[i].y<map[tmp].y)||(map[i].y==map[tmp].y&&map[i].x<map[tmp].x))
tmp=i;
}
Point p=map[tmp];
map[tmp]=map[0];
map[0]=p;
sort(map+1,map+n,cmp);
top=2;
S[0]=map[0];
S[1]=map[1];
S[2]=map[2];
for(i=3;i<n;i++)
{
while(XieLv(map[i],S[top],S[top-1])>0)
top--;
S[++top]=map[i];
}
return top+1;
}
int main()
{
int i,num;
double ans=0.0;
cin>>n>>L;
for(i=0;i<n;i++)
{
scanf("%d %d",&map[i].x,&map[i].y);
}
num=Graham();
for(i=0;i<num-1;i++)
{
ans+=Dis(S[i],S[i+1]);
}
ans+=Dis(S[num-1],S[0]);
ans=ans+2*L*PI;
printf("%.0f\n",ans);
return 0;
}