模拟退火 poj 1379
t
X Y n
求一个点 到n个点最短距离 最大
#include<stdio.h> #include<algorithm> #include<time.h> #include<math.h> using namespace std; #define NUM 20 #define RAD 1000 class point { public: point(){} point(double xx,double yy) { this->x=xx; this->y=yy; } double x,y,val; }; point p[10001],May[NUM]; int n; double X,Y; double dis(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } double jud(point a)//求出最大的
{ double len; len=1LL<<45; for(int i=0;i<n;i++) len=min(len,dis(a,p[i])); return len; } double Rand() //生成一个随机数 { return rand()%(RAD+1)/(1.0*RAD); } point Rand_point(point a,point b) //这2个点之间随机的一个 { double x=a.x+(b.x-a.x)*Rand(); double y=a.y+(b.y-a.y)*Rand(); point tmp=point(x,y); tmp.val=jud(tmp); return tmp; } void solve(double D) { May[0]=point(0,0); May[1]=point(X,0); May[2]=point(0,Y); May[3]=point(X,Y); //4个特殊的点 for(int i=4;i<NUM;i++) May[i]=Rand_point(May[0],May[3]); while(D>0.01) { for(int i=0;i<NUM;i++) { for(int j=0;j<NUM;j++) //每个点周围产生20个点 { point tmp=Rand_point(point(max(0.0,May[i].x-D),max(0.0,May[i].y-D)),point(min(X,May[i].x+D),min(Y,May[i].y+D))); if(tmp.val>May[i].val) May[i]=tmp; } } D*=0.9; } point ans; ans.val=0; for(int i=0;i<NUM;i++) if(May[i].val>ans.val) ans=May[i]; printf("The safest point is (%.1lf, %.1lf).\n",ans.x,ans.y); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%lf%lf%d",&X,&Y,&n); for(int i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); solve(max(X,Y)); } return 0; }
posted on 2017-02-08 14:29 HelloWorld!--By-MJY 阅读(131) 评论(0) 编辑 收藏 举报