题意:
给一个矩形和在其中的n个点,要求一个到所有点距离最小值最大的点。
思路:
用简化的退火算法即随机化变步长贪心方法解决,还是用了退火算法的思路。
代码:
//poj 1379
//sepNINE
#include <iostream>
#include <cmath>
using namespace std;
const int maxN=1024;
const int NUM=20;
const int PRECISION=10000;
const int TIM=30;
const double MIN=1e-3;
const double alpha=0.8;
int n;
double maxX,maxY;struct Point
{double x,y,v;Point(){}Point(double x,double y):x(x),y(y){}
}pnt[maxN],randPnt[NUM];double getDouble(){return (rand()%(PRECISION+1))*1.0/PRECISION;
}double getMin(Point p)
{double ans=1e8;for(int i=0;i<n;++i)ans=min(ans,sqrt((p.x-pnt[i].x)*(p.x-pnt[i].x)+(p.y-pnt[i].y)*(p.y-pnt[i].y)));return ans;
}Point getRandPnt(Point a,Point b)
{Point p(a.x+(b.x-a.x)*getDouble(),a.y+(b.y-a.y)*getDouble());if(p.x>maxX) p.x=maxX;if(p.x<0) p.x=0;if(p.y>maxY) p.y=maxY;if(p.y<0) p.y=0;p.v=getMin(p);return p;
} void search(double maxL)
{for(double L=maxL;L>=MIN;L=L*alpha)for(int i=0;i<NUM;++i)for(int j=0;j<TIM;++j){Point tmp=getRandPnt(Point(randPnt[i].x-L,randPnt[i].y-L),Point(randPnt[i].x+L,randPnt[i].y+L));if(tmp.v>randPnt[i].v)randPnt[i]=tmp;}
}int main()
{int cases;scanf("%d",&cases);while(cases--){int i;scanf("%lf%lf%d",&maxX,&maxY,&n);for(i=0;i<n;++i)scanf("%lf%lf",&pnt[i].x,&pnt[i].y); Point a(0,0),b(maxX,maxY);for(i=0;i<NUM;++i)randPnt[i]=getRandPnt(a,b);search(max(b.x,b.y));double ans=randPnt[0].v;int ansI=0;for(i=0;i<NUM;++i)if(ans<randPnt[i].v){ans=randPnt[i].v;ansI=i; }printf("The safest point is (%.1lf, %.1lf).\n",randPnt[ansI].x,randPnt[ansI].y);}return 0;
}