ch_g

ECUST_ACMer —— ch_g
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[POJ][3285][Point of view in Flatland][模拟退火]

Posted on 2011-03-09 11:44  ch_g  阅读(384)  评论(0编辑  收藏  举报
/*
题目:Point of view in Flatland
题目来源:POJ 3285
题目难度:中等偏难
题目内容或思路:
模拟退火
这题的难点在找到合适的评估函数
做题日期:2011.3.9
*/
#include
<cstdio>
#include
<cstdlib>
#include
<climits>
#include
<iostream>
#include
<algorithm>
#include
<cstring>
#include
<string>
#include
<queue>
#include
<map>
#include
<vector>
#include
<bitset>
#include
<cmath>
#include
<set>
#include
<utility>
#include
<ctime>
#define sqr(x) ((x)*(x))
using namespace std;

const int N = 30, nt = 20, step = 30;
const double inf = 1e100;
const double eps = 1e-3;
const double pi = acos(-1.0);
double delta;

struct cpoint{
double x, y, r;
}cp[N], test[N];

int dcmp(double x) {
if (x < -eps) return -1; else return x > eps;
}

double dis(cpoint a, cpoint b) {
return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));
}

void calc(cpoint &p) {
double t[3], ave = 0;
int id = 0;
for (int i = 0; i < 3; ++i) {
t[i]
= dis(p, cp[i]) / cp[i].r;
ave
+= t[i];
}
ave
/= 3;
p.r
= 0;
for (int i = 0; i < 3; ++i) {
p.r
+= sqr(t[i] - ave);
}
}

void updata(int id) {
cpoint t;
double angle = rand();
angle
-= int(angle / pi / 2) * pi * 2;
t.x
= test[id].x + delta * cos(angle);
t.y
= test[id].y + delta * sin(angle);
calc(t);
if (t.r < test[id].r)
test[id]
= t;
}

bool solve() {
double t = 0, maxx, minx, maxy, miny;
maxx
= maxy = -inf;
minx
= miny = inf;
for (int i = 0; i < 3; ++i) {
scanf(
"%lf%lf%lf", &cp[i].x, &cp[i].y, &cp[i].r);
t
+= cp[i].r;
maxx
= max(maxx, cp[i].x);
minx
= min(minx, cp[i].x);
maxy
= max(maxy, cp[i].y);
miny
= min(miny, cp[i].y);
}
if (dcmp(t) == 0) return false;
for (int i = 0; i < nt; ++i) {
test[i].x
= minx + (rand() % (int)(maxx * 10 - minx * 10 + 1)) / 10.0;
test[i].y
= miny + (rand() % (int)(maxy * 10 - miny * 10 + 1)) / 10.0;
calc(test[i]);
}
delta
= max(maxx - minx, maxy - miny);
for (; delta > 1e-6; delta *= 0.9) {
for (int i = 0; i < nt; ++i)
for (int j = 0; j < step; ++j)
updata(i);
}
int res = -1;
for (int i = 0; i < nt; ++i) {
if (dcmp(test[i].r) == 0) {
double u = dis(test[i], cp[0]);
double v = dis(test[res], cp[0]);
if (res == -1 || dcmp(u - v) < 0)
res
= i;
}
}
if (res == -1) puts("No solution");
else {
if (dcmp(test[res].x) == 0) test[res].x = 0;
if (dcmp(test[res].y) == 0) test[res].y = 0;
printf(
"%.2lf %.2lf\n", test[res].x, test[res].y);
}
return true;
}

int main() {
#ifndef ONLINE_JUDGE
freopen(
"D:\\in.txt", "r", stdin);
#endif
while (solve());
return 0;
}