2018南京-Country Meow-(模拟退火)

D

题意:
就是给你n个点,问你在那个点是到所有点距离的最大值最小。

思考:
一看就是几何题,但是怎么做呢,好像有啥板子才行。然后答案让你输出小数点后几位的,一般答案都可以不太精确即可。所以如果能退火就退火,这个也就是先选一个点,然后随机下一个点,如果当前的最小值更优,那么就过去。跑10次退火取答案最好的时候即可。

代码:

struct point{
	db x,y,z;
}node[N];

int T,n,m,k;
int va[N];
db anw = inf;

db dis(db x,db y,db z)
{
	db sum = 0;
	for(int i=1;i<=n;i++)
	{
		db res = 0;
		res += (x-node[i].x)*(x-node[i].x);
		res += (y-node[i].y)*(y-node[i].y);
		res += (z-node[i].z)*(z-node[i].z);
		sum = max(sum,sqrt(res));
	}
	return sum;
}

void SA()
{
	db te = 3000,delt = 0.99,eps = 1e-15;
	db x = 0,y = 0,z = 0,ans = inf;
	while(te>eps)
	{
		db xx = x+(rand()*2-RAND_MAX)*te;
		db yy = y+(rand()*2-RAND_MAX)*te;
		db zz = z+(rand()*2-RAND_MAX)*te;
		db ans_t = dis(xx,yy,zz);
		db pro = exp((ans-ans_t)/te)*RAND_MAX;
		if(ans>ans_t||pro>rand())
		{
			ans = ans_t;
			x = xx,y = yy,z = zz;
		}
		te *= delt;
	}
	anw = min(anw,ans);
}

signed main()
{
	IOS;
	srand(time(NULL));
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		db a,b,c;
		cin>>a>>b>>c;
		node[i] = {a,b,c};
	}
	for(int i=1;i<=10;i++) SA();
	printf("%.8lf",anw);
	return 0;
}

总结:
多多积累经验。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值