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;
}

 

posted @ 2010-07-30 17:34  勇泽  阅读(546)  评论(0编辑  收藏  举报