poj 1379 分类: poj templates 2015-08-08 22:17 3人阅读 评论(0) 收藏


传说正解是V图,想想都觉得难写。。。


模拟退火~ 随机取几个点,将温度设置为随机范围,然后随机爬山算法即可。。。

如果参数设置得比较优,就可以在精度范围内取得最优解。。。

所以暂时就不学V图了(反正写不出)


注意如果用G++交题的话,要用 %f 输出。。。

我以后还是用C++交题吧,虽然语法比较严格,但不像G++那样不规范。。。


#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <utility>
#include <iostream>
#include <algorithm>

template<class Num>void read(Num &x)
{
    char c; int flag = 1;
    while((c = getchar()) < '0' || c > '9')
        if(c == '-') flag *= -1;
    x = c - '0';
    while((c = getchar()) >= '0' && c <= '9')
        x = (x<<3) + (x<<1) + (c-'0');
    x *= flag;
    return;
}
template<class Num>void write(Num x)
{
    if(x < 0) putchar('-'), x = -x;
    static char s[20];int sl = 0;
    while(x) s[sl++] = x%10 + '0',x /= 10;
    if(!sl) {putchar('0');return;}
    while(sl) putchar(s[--sl]);
}

const int maxm = 1005, ways = 60, Num = 20, Rad = 1000;
const double eps = 1e-2, pi = acos((double)-1), DINF = 1e8, reduce = 0.90, zero = 0;

int X, Y, M;
double T;

struct Node
{
    double x, y;

    void init()
    {
        scanf("%lf%lf",&x,&y);
    }
}node[maxm], now, att, ans;

double maxd, ansd;

void init()
{
    read(X), read(Y), read(M);

    for(int i = 1; i <= M; i++) node[i].init();
}
double Rand()
{
    return (double)(rand()%(Rad + 1))/Rad;
}

double calcu(const Node &p)
{
    double minc = DINF;

    for(int i = 1; i <= M; i++)
        minc = std::min(minc, sqrt((node[i].x - p.x)*(node[i].x - p.x) + (node[i].y - p.y)*(node[i].y - p.y)));

    return minc;
}
void solve()
{

    for(int E = 1; E <= Num; E++)
    {
        T = sqrt((double)X*X + Y*Y);

        if(E == 1)
            now.x = 0, now.y = 0;
        else if(E == 2)
            now.x = 0, now.y = Y;
        else if(E == 3)
            now.x = X, now.y = 0;
        else if(E == 4)
            now.x = X, now.y = Y;
        else
        {   
            now.x = ((long long)rand()*rand())%X + Rand();
            now.y = ((long long)rand()*rand())%Y + Rand();
        }

        maxd = calcu(now);

        while(T > eps)
        {
            for(int i = 1; i <= ways; i++)
            {
                int xlen = std::min(now.x + T, (double)X) - std::max(now.x - T, zero);
                int ylen = std::min(now.y + T, (double)Y) - std::max(now.y - T, zero);

                att.x = std::max(now.x - T, zero) + Rand()*xlen;
                att.y = std::max(now.y - T, zero) + Rand()*ylen;

                double tmp = calcu(att);

                if(tmp > maxd) maxd = tmp, now = att;
            }

            T *= reduce;
        }

        if(E == 1 || maxd > ansd) ans = now, ansd = maxd;
    }
    printf("The safest point is (%.1lf, %.1lf).\n", ans.x, ans.y);

}

int main()
{
    int Case;

#ifndef ONLINE_JUDGE    
    freopen("1379.in","r",stdin);
    freopen("1379.out","w",stdout);
#endif

    srand(16384);

    read(Case);

    while(Case--)
    {
        init();
        solve();
    }


#ifndef ONLINE_JUDGE
    fclose(stdin);
    fclose(stdout);
#endif
    return 0;   
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-08-08 22:17  <Dash>  阅读(132)  评论(0编辑  收藏  举报