POJ - 1379 Run Away 爬山演算法
阿新 • • 發佈:2019-01-02
題意:
給出一個矩陣,在矩陣中有一些陷阱,計算矩陣上的一個點到所有陷阱的最短距離最大的點。
分析:
由於搜尋空間較大,所以採用隨機演算法,然而試了半天模擬退火,但是精確度不夠,換上爬山演算法,勉強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; }