模拟退火

23 篇文章 0 订阅
16 篇文章 0 订阅

骗分神码,只不过还是要看RP,脸黑的我怕是要哭死在大街上了

描述

g t y gty gty又虐了一场比赛,被虐的蒟蒻们决定吊打 g t y gty gty g t y gty gty见大势不好机智的分出了 n n n个分身,但还是被人多势众的蒟蒻抓住了。蒟蒻们将 n n n g t y gty gty吊在 n n n根绳子上,每根绳子穿过天台的一个洞。这 n n n根绳子有一个公共的绳结 x x x。吊好 g t y gty gty后蒟蒻们发现由于每个 g t y gty gty重力不同,绳 结 x x x在移动。蒟蒻 w a n g x z wangxz wangxz脑洞大开的决定计算出 x x x最后停留处的坐标,由于他太弱了决定向你求助。 不计摩擦,不计能量损失,由于 g t y gty gty足够矮所以不会掉到地上。

输入

输入第一行为一个正整数 n ( 1 &lt; = n &lt; = 10000 ) n(1&lt;=n&lt;=10000) n(1<=n<=10000),表示 g t y gty gty的数目。
接下来n行,每行三个整数 x i , y i , w i , xi,yi,wi, xiyiwi表示第 i i i g t y gty gty的横坐标,纵坐标和重力。

输出

输出 1 1 1行两个浮点数(保留到小数点后 3 3 3位),表示最终 x x x的横、纵坐标。

样例输入
3
0 0 1
0 2 1
1 1 1
样例输出
0.577 1.000
提示

对于 20 20 20%的数据, g t y gty gty排列成一条直线。

对于 50 50 50%的数据, 1 &lt; = n &lt; = 1000 1&lt;=n&lt;=1000 1<=n<=1000

对于 100 100 100%的数据, 1 &lt; = n &lt; = 10000 , − 100000 &lt; = x i , y i &lt; = 100000 1&lt;=n&lt;=10000,-100000&lt;=xi,yi&lt;=100000 1<=n<=10000,100000<=xi,yi<=100000

CODE
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int read(){
	int s=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') f=-f;
		ch=getchar();
	}
	while(isdigit(ch)){
		s=(s<<3)+(s<<1)+ch-'0';
		ch=getchar();
	}
	return s*f;
}
struct fjy{
	int w,x,y;
}l[N];
int n;
long double xans,yans;
const double delta=0.9824;
double t,ans=1e18+7;
double potential_energy(double xx,double yy){
	double sum=0;
	for(int i=1;i<=n;i++){
		double disx=l[i].x-xx,disy=l[i].y-yy;
		sum+=sqrt((disx*disx)+(disy*disy))*l[i].w;
	}
	return sum;
} 
void simulate_anneal(){
	t=2003;
	double xx=xans,yy=xans;
	while(t>1e-14){
		double xtemp=xans+(rand()*2-RAND_MAX)*t;
		double ytemp=yans+(rand()*2-RAND_MAX)*t;
		double new_ans=potential_energy(xtemp,ytemp);
		double DE=new_ans-ans;
		if(DE<0){
			xx=xtemp;
			yy=ytemp;
			xans=xtemp;
			yans=ytemp;
			ans=new_ans;
		}
		else if(exp(-DE/t)*RAND_MAX>rand()){
			xx=xtemp;
			yy=ytemp;
			xans=xtemp;
			yans=ytemp;
			ans=new_ans;
		}
		t*=delta;
	}
}
void SA(){
	simulate_anneal();
	simulate_anneal();
	simulate_anneal();
}
int main(){
	srand(19260817);
	n=read();
	for(int i=1;i<=n;i++){
		l[i].x=read();
		l[i].y=read();
		l[i].w=read();
	}
	SA();
	printf("%.4Lf %.4Lf",xans,yans);
}

链接:https://www.cnblogs.com/Le-mon/p/9072859.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值