[JSOI2004]平衡点

题目:洛谷P1337。

题目大意:
有n个重物,每个重物有一个重量w,并且绑在一条绳子上。这些绳子在桌面上打成一个结。问结在哪里才能使重物平衡。
解题思路:
题意就是要求\(\sum\limits_{i=1}^n d_i\times w_i\)最小(\(d_i\)为重物i到结的距离)。
模拟退火即可。

C++ Code:

#include<bits/stdc++.h>
#define eps 1e-15
#define delta 0.991
struct things{
	int x,y,w;
}p[1005];
struct Answer{
	double x,y,w;
}ans,start,now;
int n,xxx=0,yyy=0;
inline int readint(){
	int d=0,c=getchar(),f=0;
	for(;!isdigit(c);c=getchar())f=c=='-';
	for(;isdigit(c);c=getchar())d=(d<<3)+(d<<1)+(c^'0');
	return f?-d:d;
}
inline double calc(const double xx,const double yy){
	double r=0;
	for(int i=1;i<=n;++i){
		double x=p[i].x-xx,y=p[i].y-yy;
		r+=sqrt(x*x+y*y)*p[i].w;
	}
	return r;
}
int main(){
	n=readint();
	for(int i=1;i<=n;++i){
		xxx+=(p[i].x=readint()),yyy+=(p[i].y=readint());
		p[i].w=readint();
	}
	ans=start=(Answer){1.*xxx/n,1.*yyy/n,calc(1.*xxx/n,1.*yyy/n)};
	srand(time(0));
	for(int T=20;T;--T){
		now=start;
		for(double nT=5333;nT>eps;nT*=delta){
			double nx=now.x+((rand()<<1ll)-RAND_MAX)*nT;
			double ny=now.y+((rand()<<1ll)-RAND_MAX)*nT;
			double res=calc(nx,ny);
			if(res<ans.w)ans=(Answer){nx,ny,res};
			if(res<now.w||exp((res-now.w)/nT)*RAND_MAX<rand())
			now=(Answer){nx,ny,res};
		}
	}
	printf("%.3f %.3f\n",ans.x,ans.y);
	return 0;
}

 

转载于:https://www.cnblogs.com/Mrsrz/p/9179136.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值