模拟退火 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). ",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; }
原文地址:https://www.cnblogs.com/cherryMJY/p/6378047.html