一个最小 一个最大 poj 1379 hdu 3932

两个题目一个是求一个点,使得该点到n个点的最大距离的最小值

另一个是求一个点,使得该点到n个点的最小距离的最大值

好像也不是什么模拟退火的做法,只是一种利用随机函数的做法,遍历一下整个区域找到最优解

poj 1379

View Code
//在某个区域内到某个点集的最小距离最大
//随机算法解决
//dis[i]表示点i到点集中最小距离的最大值
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#include<time.h>
const double inf = 1e10;
const double pi = acos(-1.0);
const int Rp = 4;//初始时随机选择一些点,不用太多
const int shift = 100;//但是方向一定要多
struct point {
double x,y;
void goto_rand_dir(double key)
{
double d=2*pi*(double)rand()/RAND_MAX;
x+=key*sin(d);
y+=key*cos(d);
}
void Get_Rand_Point(int a,int b)
{
x=rand()%a+1;
y=rand()%b+1;
}
}p[1010],randp[Rp];
double Dis(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
double dis[Rp];
int main()
{
int t,i,j,k,x,y,m;
scanf("%d",&t);
srand(time(NULL));
while(t--)
{
scanf("%d%d%d",&x,&y,&m);
for(i=0;i<m;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
double tmp;
for(i=0;i<Rp;i++)
{
dis[i]=inf;
randp[i].Get_Rand_Point(x,y);
for(j=0;j<m;j++)
{
tmp=Dis(randp[i],p[j]);
if(tmp<dis[i])
dis[i]=tmp;
}
}
double key=sqrt(1.0*(x*x+y*y))/2;//初始的步长
while(key>=0.01)
{
for(i=0;i<Rp;i++)
{
for(j=0;j<shift;j++)
{
point cc=randp[i];
cc.goto_rand_dir(key);
if(cc.x<0||cc.y<0||cc.x>x||cc.y>y) continue;
tmp=inf;
for(k=0;k<m;k++)
{
double di=Dis(cc,p[k]);
if(di<tmp)
tmp=di;
}
if(tmp>dis[i]) //如果从i点出发随机移动的点比原来的点更优,则接受该移动
{
dis[i]=tmp;
randp[i]=cc;
}
}
}
key=key*0.7;
}
for(i=k=0;i<Rp;i++)
if(dis[i]>dis[k])
k=i;
printf("The safest point is (%.1lf, %.1lf).\n",randp[k].x,randp[k].y);
}
return 0;
}


hdu 3932 

http://www.cnblogs.com/wuyiqi/archive/2011/12/08/2280473.html

posted @ 2011-12-08 15:42  Because Of You  Views(1136)  Comments(0Edit  收藏  举报