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

 

你可能感兴趣的:(poj)