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的主要内容,如果未能解决你的问题,请参考以下文章

poj1379 Run Away

POJ.1379.Run Away(模拟退火)

POJ 1379 Run Away(模拟退火)

BZOJ1844/2210Pku1379 Run Away 模拟退火

PKU 1379 Run Away(模拟退火算法)

POJ 1379 模拟退火