poj 1379 分类: poj templates 2015-08-08 22:17 3人阅读 评论(0) 收藏
传说正解是
模拟退火~ 随机取几个点,将温度设置为随机范围,然后随机爬山算法即可。。。
如果参数设置得比较优,就可以在精度范围内取得最优解。。。
所以暂时就不学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;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。