POJ 1379 Run Away
Posted GFY
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 1379 Run Away相关的知识,希望对你有一定的参考价值。
题意:有n个陷阱,在X,Y范围内要求出一个点使得这个点到陷阱的最小距离最大。
思路:模拟退火,随机撒入40个点,然后模拟退火随机化移动。
(这题poj坑爹,加了srand(time(NULL))不能交G++,不加srand(time(NULL))又会WA,交了C++不能用acos(-1),只能用3.1415926代替,真是坑爹。)
#include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<iostream> #include<time.h> #define N 10005 const double eps=1e-3; const double Pi=3.1415926;//acos(-1)! struct Point{ double x,y; Point(){} Point(double x0,double y0):x(x0),y(y0){} }p[N],q[N]; double d[N]; int X,Y,n; double dis(Point p1){ return p1.x*p1.x+p1.y*p1.y; } double dist(Point p1,Point p2){ return sqrt(dis(Point(p1.x-p2.x,p1.y-p2.y))); } int main(){ srand(time(NULL)); int T; scanf("%d",&T); while (T--){ scanf("%d%d%d",&X,&Y,&n); for (int i=1;i<=n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); for (int i=1;i<=40;i++){ q[i].x=(double)((double)((rand()%1000+1)))/1000.0*X; q[i].y=(double)((double)((rand()%1000+1)))/1000.0*Y; d[i]=1e20; for (int j=1;j<=n;j++) d[i]=std::min(d[i],dist(q[i],p[j])); } double kt=(double)((double)(std::max(X,Y)))/sqrt(1.0*n); while (kt>eps){ for (int i=1;i<=40;i++){ double qx=q[i].x,qy=q[i].y; for (int j=1;j<=40;j++){ double theta=double(((double)(rand()%1000+1))/1000.0)*10*Pi; double dx=kt*cos(theta); double dy=kt*sin(theta); double tx=qx+dx,ty=qy+dy; if (tx<0||tx>X||ty<0||ty>Y) continue; double td=1e20; for (int k=1;k<=n;k++) td=std::min(td,dist(Point(tx,ty),p[k])); if (td>d[i]){ d[i]=td; q[i]=Point(tx,ty); } } } kt*=0.8; } double ans=0; Point Ans; for (int i=1;i<=40;i++) if (ans<d[i]){ ans=d[i]; Ans=q[i]; } printf("The safest point is (%.1lf, %.1lf).\n",Ans.x,Ans.y); } }
以上是关于POJ 1379 Run Away的主要内容,如果未能解决你的问题,请参考以下文章