POJ 1379 (随机算法)模拟退火

时间:2023-03-09 23:43:41
POJ 1379 (随机算法)模拟退火

题目大意:

给定一堆点,找到一个点的位置使这个点到所有点中的最小距离最大

这里数据范围很小,精度要求也不高,我们这里可以利用模拟退火的方法,随机找到下一个点,如果下一个点比当前点优秀就更新当前点

参考:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

http://wenku.baidu.com/view/0c6b5df5f61fb7360b4c65a9.html

 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <climits>
#include <cmath>
#include <queue>
#include <cstdlib>
#include <ctime>
using namespace std;
#define random(x) ((rand()%x)+1)
#define N 1005
#define ll long long
#define eps 1e-4
const double PI = acos(-1.0);
const int INF = INT_MAX;
const int P = ;
const int L = ; double x,y;
int n;
double dist[N]; struct Point{
double x,y;
Point(double x= , double y=):x(x),y(y){}
}p[N] , tmp[N]; double dis(Point a , Point b)
{
double x = a.x-b.x , y = a.y - b.y;
return sqrt(x*x+y*y);
} double min_dis(Point t)
{
double minn = 1e20;
for(int i= ; i<n ; i++) minn=min(minn , dis(t , p[i]));
return minn;
} bool ok(Point t)
{
return t.x>= && t.x<=x && t.y>= && t.y<=y;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in" , "r" , stdin);
#endif // ONLINE_JUDGE
srand(time());
int T;
scanf("%d" , &T);
while(T--)
{
Point ans;
double ret=; scanf("%lf%lf%d" , &x , &y , &n);
for(int i= ; i<n ; i++){
scanf("%lf%lf" , &p[i].x , &p[i].y);
} for(int i= ; i<P ; i++){
tmp[i].x = random()/1000.0*x;
tmp[i].y = random()/1000.0*y;
dist[i] = min_dis(tmp[i]);
}
double step = sqrt(x*x+y*y)/;
while(step>eps){ for(int i= ; i<P ; i++){
Point cur;
for(int j= ; j<L ; j++){
double ang = random()/1000.0**PI;
cur.x = tmp[i].x+cos(ang)*step;
cur.y = tmp[i].y+sin(ang)*step;
if(!ok(cur)) continue;
double val = min_dis(cur);
if(val>dist[i]){
tmp[i]=cur;
dist[i] = val;
}
}
}
step *= 0.85;
} for(int i= ; i<P ; i++){
if(dist[i]>ret){
ret = dist[i];
ans = tmp[i];
}
}
printf("The safest point is (%.1f, %.1f).\n" , ans.x , ans.y);
}
return ;
}