OJ-Problems-Source/HDOJ/3644_autoAC.cpp

138 lines
3.4 KiB
C++

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn = 100;
const double eps = 1e-3;
const int times = 5;
const double INF = 99999999;
int n;
struct point
{
double x, y, r;
} p[maxn], test[maxn];
inline int dblcmp( double x )
{
if( fabs(x) < eps )
return 0;
return x > 0 ? 1 : -1;
}
inline double sqr( double x )
{
return x*x;
}
double dis( point& aa, point& bb )
{
return sqrt(sqr(aa.x-bb.x)+sqr(aa.y-bb.y));
}
double cross( point& k, point& aa, point& bb )
{
return (k.x-aa.x)*(k.y-bb.y)-(k.y-aa.y)*(k.x-bb.x);
}
double seg_point_dis( point& l1, point& l2, point& k )
{
double a, b, c;
a = dis(l1, k);
b = dis(l2, k);
c = dis(l1, l2);
if( dblcmp(a*a+c*c-b*b) < 0 )
return a;
else if( dblcmp(b*b+c*c-a*a) < 0 )
return b;
else
return fabs(cross(k, l1, l2)/c);
}
bool point_inside( point& aa )
{
int i, cnt = 0;
double t;
for( i = 0; i < n; ++i )
{
if( (p[i].y <= aa.y && p[i+1].y > aa.y) ||
(p[i+1].y <= aa.y && p[i].y > aa.y) )
{
if( !dblcmp(p[i].y-p[i+1].y) )
{
if( dblcmp(p[i].y-aa.y) == 0 )
cnt++;
t = -INF;
}
else
t = p[i+1].x - (p[i+1].x-p[i].x)*(p[i+1].y-aa.y)/(p[i+1].y-p[i].y);
if( dblcmp( t - aa.x ) >= 0 )
cnt++;
}
}
return cnt%2;
}
void cal( point& aa )
{
double t;
aa.r = INF;
for( int i = 0; i < n; ++i )
{
t = seg_point_dis(p[i], p[i+1], aa);
aa.r = min(aa.r, t);
}
}
int main()
{
int i, j;
double R, delte, maxx, maxy, minx, miny, ang;
point temp;
bool ok;
while( scanf("%d", &n), n )
{
ok = 0;
maxx = maxy = 0;
minx = miny = INF;
for( i = 0; i < n; ++i )
{
scanf("%lf %lf", &p[i].x, &p[i].y);
maxx = max(maxx, p[i].x);
maxy = max(maxy, p[i].y);
minx = min(minx, p[i].x);
miny = min(miny, p[i].y);
}
p[n] = p[0];
for( i = 0; i < n; ++i )
{
test[i].x = (p[i].x+p[i+1].x)/2;
test[i].y = (p[i].y+p[i+1].y)/2;
test[i].r = 0;
}
scanf("%lf", &R);
maxx -= minx; maxy -= miny;
delte = sqrt(maxx*maxx+maxy*maxy)/2;
while( !ok && delte > eps )
{
for( i = 0; !ok && i < n; ++i )
{
for( j = 0; !ok && j < times; ++j )
{
ang = rand();
temp.x = test[i].x + delte*cos(ang);
temp.y = test[i].y + delte*sin(ang);
if( point_inside(temp) )
{
cal(temp);
if( temp.r > test[i].r )
{
test[i] = temp;
if( dblcmp(temp.r-R) >= 0 )
ok = 1;
}
}
}
}
delte *= 0.90;
}
if( ok )
printf("Yes\n");
else
printf("No\n");
}
return 0;
}