A Round Peg in a Ground Hole--POJ 1584

1、题目类型:模拟、计算几何。

2、解题思路:(1)检测是否为凹多边形;(2)检测圆心是否在凸多边形内部;(3)检测圆心到多边形所有边的距离是否小于半径 (具体见实现代码)。

3、注意事项:注意多边形的顺时针和逆时针,由于上的是模板,所以细节考虑并不多。

4、实现方法:

  
    
#include < iostream >
#include
< cmath >
#define MIN(x,y) (x < y ? x : y)
#define MAX(x,y) (x > y ? x : y)
using namespace std;

struct Point
{
double x,y;
};

int n;
double r;
Point P[
160 ];
Point c;

// 检测是否为凹多边形: *p表示为多边形序列,n表示为多边形顶点数
int Check1(Point * p, int n)
{
int i,j,k,flag = 0 ;
double z;
if (n < 3 )
return ( 0 );
for (i = 0 ;i < n;i ++ )
{
j
= (i + 1 ) % n;
k
= (i + 2 ) % n;
z
= (p[j].x - p[i].x) * (p[k].y - p[j].y);
z
-= (p[j].y - p[i].y) * (p[k].x - p[j].x);
if (z < 0 )
flag
|= 1 ;
else if (z > 0 )
flag
|= 2 ;
if (flag == 3 )
return 0 ;
}
if (flag != 0 )
return 1 ;
else
return 0 ;
}

// 检测点是否在多边形内: *polygon表示为多边形序列,n表示为多边形顶点数,p表示为点
int Check2(Point * polygon, int N,Point p)
{
int i,counter = 0 ;
double xinters;
Point p1,p2;
p1
= polygon[ 0 ];
for (i = 1 ;i <= N;i ++ )
{
p2
= polygon[i % N];
if (p.y > MIN(p1.y,p2.y))
{
if (p.y <= MAX(p1.y,p2.y))
{
if (p.x <= MAX(p1.x,p2.x))
{
if (p1.y != p2.y)
{
xinters
= (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x;
if (p1.x == p2.x || p.x <= xinters)
counter
++ ;
}
}
}
}
p1
= p2;
}
if (counter % 2 == 0 )
return 1 ;
else
return 0 ;
}

// 计算点到线段的最短距离:p1,p2表示线段的两点,q表示距离点
double Mindistance(Point p1,Point p2,Point q)
{
int flag = 1 ;
double k;
Point s;
if (p1.x == p2.x) {s.x = p1.x;s.y = q.y;flag = 0 ;}
if (p1.y == p2.y) {s.x = q.x;s.y = p1.y;flag = 0 ;}
if (flag)
{
k
= (p2.y - p1.y) / (p2.x - p1.x);
s.x
= (k * k * p1.x + k * (q.y - p1.y) + q.x) / (k * k + 1 );
s.y
= k * (s.x - p1.x) + p1.y;
}
if (MIN(p1.x,p2.x) <= s.x && s.x <= MAX(p1.x,p2.x))
return sqrt((q.x - s.x) * (q.x - s.x) + (q.y - s.y) * (q.y - s.y));
else
return MIN(sqrt((q.x - p1.x) * (q.x - p1.x) + (q.y - p1.y) * (q.y - p1.y)),
sqrt((q.x
- p2.x) * (q.x - p2.x) + (q.y - p2.y) * (q.y - p2.y)));
}

int Check3()
{
int i;
P[n].x
= P[ 0 ].x;
P[n].y
= P[ 0 ].y;
for (i = 0 ;i < n;i ++ )
{
if (Mindistance(P[i],P[i + 1 ],c) < r)
return 0 ;
}
return 1 ;
}

void Solve()
{
if ( ! Check1(P,n))
{
cout
<< " HOLE IS ILL-FORMED " << endl;
return ;
}
if (Check2(P,n,c))
{
cout
<< " PEG WILL NOT FIT " << endl;
return ;
}
if ( ! Check3())
{
cout
<< " PEG WILL NOT FIT " << endl;
return ;
}
else
{
cout
<< " PEG WILL FIT " << endl;
return ;
}
}

int main()
{
int i;
while (cin >> n && n >= 3 )
{
cin
>> r >> c.x >> c.y;
for (i = 0 ;i < n;i ++ )
{
cin
>> P[i].x >> P[i].y;
}
Solve();
}
return 0 ;
}

 

你可能感兴趣的:(round)