您的位置:首页 > 其它

POJ 1379 Run Away

2016-05-27 21:25 423 查看
题意:有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
,q
;
double d
;
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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: