Beauty Contest--POJ 2187

1、题目类型:凸包。

2、解题思路:(1)建立点集map[][],为了避免负数用ADD=10000进行的处理;(2)Graham法求解凸包,中间对于斜率的排序用的是STL的sort();(3)求解凸包中点间的最大距离。

3、注意事项:凸包处理过程中,考虑是一条直线上面的情况,即使在一条直线不是一个凸包。

4、实现方法:

  
    
#include < iostream >
#include
< algorithm >
#define ADD 10000
using namespace std;

struct Point
{
int x,y;
};

int n;
Point map[
50010 ];
Point S[
50010 ];

// 求斜率
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));
}

// 两点距离的平方
int Dis(Point p1,Point p2)
{
return ((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}

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,j,len,ans = 0 ;
cin
>> n;
for (i = 0 ;i < n;i ++ )
{
scanf(
" %d %d " , & map[i].x, & map[i].y);
map[i].x
+= ADD;
map[i].y
+= ADD;
}
len
= Graham();
for (i = 0 ;i < len;i ++ )
for (j = i + 1 ;j < len;j ++ )
ans
= ans > Dis(S[i],S[j]) ? ans:Dis(S[i],S[j]);
cout
<< ans << endl;
return 0 ;
}

 

你可能感兴趣的:(test)