1. 程式人生 > >【模擬退火】poj1379 Run Away

【模擬退火】poj1379 Run Away

light algorithm 給定 一個 1.0 vector poj operator pri

題意:平面上找一個點,使得其到給定的n個點的距離的最小值最大。

模擬退火看這篇:http://www.cnblogs.com/autsky-jadek/p/7524208.html

這題稍有不同之處僅有:多隨機幾個初始點,以增加正確率。

另:WA了幾百遍竟然是因為最後輸出了-0.0這樣的值……

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
const double EPS=0.00000001;
const double PI=acos(-1.0);
struct Point{
	double x,y;
	Point(const double &x,const double &y){
		this->x=x;
		this->y=y;
	}
	Point(){}
	void read(){
		scanf("%lf%lf",&x,&y);
	}
	double length(){
		return sqrt(x*x+y*y);
	}
}a[1005],p,allp;
double ans,allans;
int n,X,Y;
typedef Point Vector;
Vector operator - (const Point &a,const Point &b){
	return Vector(a.x-b.x,a.y-b.y);
}
Vector operator + (const Vector &a,const Vector &b){
	return Vector(a.x+b.x,a.y+b.y);
}
Vector operator * (const double &K,const Vector &v){
	return Vector(K*v.x,K*v.y);
}
double calc(Point p){
	double res=1000000.0;
	for(int i=1;i<=n;++i){
		res=min(res,(a[i]-p).length());
	}
	return res;
}
int main(){
	int zu;
	srand(233);
	//freopen("poj1379.in","r",stdin);
	//freopen("poj1379.out","w",stdout);
	scanf("%d",&zu);
	for(;zu;--zu){
		allans=0.0;
		scanf("%d%d%d",&X,&Y,&n);
		p=Point(0.0,0.0);
		for(int i=1;i<=n;++i){
			a[i].read();
		}
		for(int j=1;j<=15;++j){
			p.x=(double)(rand()%(X+1));
			p.y=(double)(rand()%(Y+1));
			ans=calc(p);
			double T=sqrt((double)X*(double)X+(double)Y*(double)Y)/2.0;
//			double T=(double)max(X,Y)/sqrt((double)n);
			while(T>EPS){
				double bestnow=0.0;
				Point besttp;
				for(int i=1;i<=35;++i){
					double rad=(double)(rand()%10000+1)/10000.0*2.0*PI;
					Point tp=p+T*Point(cos(rad),sin(rad));
					if(tp.x>-EPS && tp.x-(double)X<EPS && tp.y>-EPS && tp.y-(double)Y<EPS){
						double now=calc(tp);
						if(now>bestnow){
							bestnow=now;
							besttp=tp;
						}
					}
				}
				if(bestnow>EPS && (bestnow>ans || exp((bestnow-ans)/T)*10000.0>(double)(rand()%10000))){
					ans=bestnow;
					p=besttp;
				}
				T*=0.9;
			}
			if(ans>allans){
				allans=ans;
				allp=p;
			}
		}
		printf("The safest point is (%.1f, %.1f).\n",fabs(allp.x),fabs(allp.y));
	}
	return 0;
}

【模擬退火】poj1379 Run Away