题意:求一个多边形中能否放入一个半径为R的圆。。。。
思路:凸多边形用半平面交搞定而这个有可能是凹的,所以就用模拟退火乱搞
我是枚举的每一个点走5个方向每次步长变为原来一半(5个方向其实是试出来的。因为4个方向会WA)~~~,模拟退火的题感觉就是一个火候的把握。。太多了会超时,少了又WA
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define max_n 1000000
#define inf 0x7ffffff
using namespace std;
const double eps=1e-3;
struct P
{
double x,y;
double r;
P(){}
P(double x,double y ):x(x),y(y){
}
P operator -(P p){
return P(x-p.x,y-p.y);
}
double det(P p){
return x*p.y-y*p.x;
}
double dot(P p){
return x*p.x+y*p.y;
}
};
P p[max_n],q[max_n];
int n;
double R;
int dbcmp(double k)
{
if(fabs(k)<eps)
return 0;
return k>0?1:-1;
}
bool judge(P l)
{
int k=0;
P q;
q.y=l.y;
q.x=-10000000.0;
for(int i=0;i<n;i++)
{
if(p[i].y==p[i+1].y)
continue;
if(p[i].y<p[i+1].y)
{
if(p[i].y==l.y)
continue;
}
else
{
if(p[i+1].y==l.y)
continue;
}
if((q-p[i]).det(p[i+1]-p[i])*(l-p[i]).det(p[i+1]-p[i])<=0 && (p[i]-q).det(l-q)*(p[i+1]-l).det(l-q)<=0)
k++;
}
if(k%2==0)
return 0;
return 1;
}
double dis(P a,P b)
{
double c=(a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
return sqrt(c);
}
double asd(P c,P a,P b)
{
double A,B,C;
B=1.0;
A=-((b.y-a.y)/(b.x-a.x));
C=-(A*a.x+a.y);
if(b.x-a.x==0)
{
A=1.0;
B=0.0;
C=-a.x;
}
double mm=fabs(A*c.x+B*c.y+C);
double aaa=sqrt(A*A+B*B);
return mm/aaa;
}
double segdis(P l1,P l2,P k)
{
double ll;
ll=min(dis(k,l1),dis(k,l2));
if(dbcmp((l2-l1).dot(k-l1)*(l2-l1).dot(k-l2))<=0)
ll=min(ll,asd(k,l1,l2));
return ll;
}
void solve(P &l)
{
l.r=inf;
for(int i=0;i<n;i++)
{
double kl=segdis(p[i],p[i+1],l);
l.r=min(l.r,kl);
}
}
int main()
{
while(~scanf("%d",&n) && n)
{
double mxx=-inf,mnx=inf,mxy=-inf,mny=inf;
for(int i=0;i<n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
q[i]=p[i];
mxx=max(mxx,p[i].x);
mnx=min(mnx,p[i].x);
mxy=max(mxy,p[i].y);
mny=min(mny,p[i].y);
}
p[n]=p[0];
scanf("%lf",&R);
double step=(mxx-mnx)*(mxx-mnx)+(mxy-mny)*(mxy-mny);
step=sqrt(step);
int flag=0;
while(step>eps)
{
if(flag)
break;
for(int i=0;i<n;i++)
{
if(flag)
break;
int lll=5;
while(lll--)
{
if(flag)
break;
P l;
double ang;
ang=rand();
l.x=q[i].x+step*cos(ang);
l.y=q[i].y+step*sin(ang);
if(judge(l))
{
solve(l);
if(l.r>q[i].r)
{
q[i]=l;
if(dbcmp(q[i].r-R)>=0)
flag=1;
}
}
}
}
step/=2.0;
}
if(flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}