//目录

POJ 1379 模拟退火

模拟退火算法,很久之前就写过一篇文章了。双倍经验题(POJ 2420)

题意:

在一个矩形区域内,求一个点的距离到所有点的距离最短的那个,最大。

这个题意,很像二分定义,但是毫无思路,也不能暴力枚举,那就模拟退火。

参考著名的ACdream,哈哈,有个共同点,那就是,大部分的代码,都没有做接受准则,这也许是acmer对智能算法的不习惯吧~~~

#include <stdio.h>
#include <math.h>
#include <algorithm>

using namespace std;

const int maxn = 1005;

int X,Y,M;
int Kase;

struct Node {
    double x,y;
}nodes[maxn];

int dx[4] = {0,0,-1,1};
int dy[4] = {-1,1,0,0};

double dist(Node a,Node b) {
    return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}

double calc(Node p) {
    double ret = 0x3f3f3f3f;
    for(int i = 0; i < M; i++)
        ret = min(ret,dist(p,nodes[i]));
    return ret;
}

int main()
{
    //freopen("in.txt","r",stdin);
    scanf("%d",&Kase);
    while(Kase--) {
        scanf("%d%d%d",&X,&Y,&M);

        for(int i = 0; i < M; i++)  scanf("%lf%lf",&nodes[i].x,&nodes[i].y);

        Node s;
        s.x = X/2;
        s.y = Y/2;

        double t = max(X,Y);
        double ansx = X/2;
        double ansy = Y/2;
        double ans = calc(s);

        Node tmp;
        tmp.x = 0;
        tmp.y = 0;
        double anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = 0;
            ansy = 0;
        }

        tmp.x = 0;
        tmp.y = Y;
        anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = 0;
            ansy = Y;
        }

        tmp.x = X;
        tmp.y = 0;
        anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = X;
            ansy = 0;
        }

        tmp.x = X;
        tmp.y = Y;
        anstmp = calc(tmp);
        if(anstmp>ans) {
            ans = anstmp;
            ansx = X;
            ansy = Y;
        }


        while(t>1e-8) {
            bool flag = true;
            while(flag) {
                flag = false;
                for(int i = 0; i < 4; i++) {
                    Node v;
                    v.x = s.x + dx[i]*t;
                    v.y = s.y + dy[i]*t;
                    if(v.x>X||v.y>Y||v.x<0||v.y<0) continue;

                    double tp = calc(v);

                    if(tp>ans) {
                        ans = tp;
                        flag = true;
                        ansx = v.x;
                        ansy = v.y;
                        s = v;
                    }
                }
            }
            t = t*0.98;
        }

        printf("The safest point is (%.1f, %.1f).\n",ansx,ansy);
    }
    return 0;
}

 

posted @ 2018-01-31 11:56  小草的大树梦  阅读(250)  评论(0编辑  收藏  举报