poj 1379 Run Away 随机化变步长贪心

题意:

给一个矩形和在其中的n个点,要求一个到所有点距离最小值最大的点。

思路:

用简化的退火算法即随机化变步长贪心方法解决,还是用了退火算法的思路。

代码:

//poj 1379
//sepNINE
#include <iostream>
#include <cmath>
using namespace std;
const int maxN=1024;
const int NUM=20;
const int PRECISION=10000;
const int TIM=30;
const double MIN=1e-3;
const double alpha=0.8;
int n;
double maxX,maxY;
 
struct Point
{
	double x,y,v;
	Point(){}
	Point(double x,double y):x(x),y(y){}	
}pnt[maxN],randPnt[NUM];

double getDouble(){
	return (rand()%(PRECISION+1))*1.0/PRECISION;
}

double getMin(Point p)
{
	double ans=1e8;
	for(int i=0;i<n;++i)
		ans=min(ans,sqrt((p.x-pnt[i].x)*(p.x-pnt[i].x)+(p.y-pnt[i].y)*(p.y-pnt[i].y)));
	return ans;
}

Point getRandPnt(Point a,Point b)
{
	Point p(a.x+(b.x-a.x)*getDouble(),a.y+(b.y-a.y)*getDouble());
	if(p.x>maxX) p.x=maxX;
	if(p.x<0) p.x=0;
	if(p.y>maxY) p.y=maxY;
	if(p.y<0) p.y=0;
	p.v=getMin(p);
	return p;
}  

void search(double maxL)
{
	for(double L=maxL;L>=MIN;L=L*alpha)
		for(int i=0;i<NUM;++i)
			for(int j=0;j<TIM;++j){
				Point tmp=getRandPnt(Point(randPnt[i].x-L,randPnt[i].y-L),Point(randPnt[i].x+L,randPnt[i].y+L));
				if(tmp.v>randPnt[i].v)
					randPnt[i]=tmp;
			}		
}

int main()
{
	int cases;
	scanf("%d",&cases);
	while(cases--)
	{
		int i;
		scanf("%lf%lf%d",&maxX,&maxY,&n);
		for(i=0;i<n;++i)
			scanf("%lf%lf",&pnt[i].x,&pnt[i].y);		
		Point a(0,0),b(maxX,maxY);
		for(i=0;i<NUM;++i)
			randPnt[i]=getRandPnt(a,b);
		search(max(b.x,b.y));
		double ans=randPnt[0].v;
		int ansI=0;
		for(i=0;i<NUM;++i)
			if(ans<randPnt[i].v){
				ans=randPnt[i].v;
				ansI=i;	
			}
		printf("The safest point is (%.1lf, %.1lf).\n",randPnt[ansI].x,randPnt[ansI].y);
	}
	return 0;	
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值