题意:
给出一个矩阵,在矩阵中有一些陷阱,计算矩阵上的一个点到所有陷阱的最短距离最大的点。
分析:
由于搜索空间较大,所以采用随机算法,然而试了半天模拟退火,但是精确度不够,换上爬山算法,勉强AC,但是还得做个小小的改变,即向8个方向搜索,提高精度。但是换上模拟退火不行这让我很纳闷。
#include<cstdio>
#include<ctime>
#include<cmath>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=1010;
int mo[8][2]={1,0,0,1,-1,0,0,-1,1,-1,-1,1,-1,-1,1,1};
struct node{
double x,y;
}a[maxn],ans,now;
int x,y,m;
double Max;
inline double dist(node a,node b){
return sqrt((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y));
}
inline double judge(node p){
double res=0x3f3f3f3f3f3f3f3f;
for(int i=1;i<=m;i++){
res=min(dist(p,a[i]),res);
}
if(res>Max){
Max=res;
ans=p;
return 1;
}
return 0;
}
inline double get_rand(){
return rand()%1000/1000.0;
}
inline void hillclimb(double T){
node tmp;
while(T>0.001){
for(int j=1;j<=25;j++){
for(int i=0;i<8;i++){
tmp.x=now.x+T*(get_rand()*2-1)*mo[i][0];
tmp.y=now.y+T*(get_rand()*2-1)*mo[i][1];
if(tmp.x<0||tmp.x>x||tmp.y<0||tmp.y>y) continue;
if(judge(tmp)) now=tmp;
}
}
T*=0.9;
}
}
int main(){
srand(time(NULL));
int T;
scanf("%d",&T);
while(T--){
Max=-1;
scanf("%d%d%d",&x,&y,&m);
for(int i=1;i<=m;i++){
scanf("%lf%lf",&a[i].x,&a[i].y);
}
now.x=x;
now.y=y;
hillclimb(100000);
printf("The safest point is (%.1f, %.1f).\n",ans.x,ans.y);
}
return 0;
}