分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > IT知识

P1337 [JSOI2004]平衡点 / 吊打XXX

发布时间:2023-09-06 02:01责任编辑:林大明关键词:暂无标签

题目描述

如图:有n个重物,每个重物系在一条足够长的绳子上。每条绳子自上而下穿过桌面上的洞,然后系在一起。图中X处就是公共的绳结。假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到地上),且忽略所有的摩擦。

问绳结X最终平衡于何处。

注意:桌面上的洞都比绳结X小得多,所以即使某个重物特别重,绳结X也不可能穿过桌面上的洞掉下来,最多是卡在某个洞口处。

输入输出格式

输入格式:

文件的第一行为一个正整数n(1≤n≤1000),表示重物和洞的数目。接下来的n行,每行是3个整数:Xi.Yi.Wi,分别表示第i个洞的坐标以及第 i个重物的重量。(-10000≤x,y≤10000, 0<w≤1000 )

输出格式:

你的程序必须输出两个浮点数(保留小数点后三位),分别表示处于最终平衡状态时绳结X的横坐标和纵坐标。两个数以一个空格隔开。

输入输出样例

输入样例#1: 
30 0 10 2 11 1 1
输出样例#1: 
0.577 1.000

说明

[JSOI]

Solution:

  本题裸的模拟退火(调参是真的烦!)。

  简单来讲,退火就是随机化,若随机的值的解比当前解优时就选择随机的值,当比当前的解差时有一定的概率会选择往差的解方向移动,而当移动超过某一界限时就可能出现更好的解。

  那么这个调参是真的复杂,我们的T一定要赋的够大,然要后多次迭代,每次移动时我试了贼久,选择了$0.99$,然后T的变化率$r$我选择了$0.95$。

  最后迭代完后再随便跑几次,随机一下最优解。

  反正调着调着就过了。

代码:

 1 #include<bits/stdc++.h> 2 #include<ctime> 3 #define il inline 4 #define ll long long 5 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) 6 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--) 7 #define Max(a,b) ((a)>(b)?(a):(b)) 8 #define Min(a,b) ((a)>(b)?(b):(a)) 9 using namespace std;10 const int N=10005;11 int n;12 double w[N],minn=9223372036854775807.0,T=1000000,r=0.995;13 struct node{14 ????double x,y;15 }a[N],now,ans,tp;16 17 il double Rand(){return rand()%10000/10000.0;}18 19 il double solve(node tp){20 ????double ret=0;21 ????For(i,1,n) ret+=w[i]*sqrt((tp.x-a[i].x)*(tp.x-a[i].x)+(tp.y-a[i].y)*(tp.y-a[i].y));22 ????if(ret<minn) ans=tp,minn=ret;23 ????return ret;24 }25 26 int main(){27 ????srand(2336666);28 ????cin>>n;29 ????For(i,1,n) scanf("%lf%lf%lf",&a[i].x,&a[i].y,&w[i]),now.x+=a[i].x,now.y+=a[i].y;30 ????now.x/=n,now.y/=n;31 ????solve(now);32 ????For(i,1,10){33 ????????T=6000000;34 ????????while(T>0.001){35 ????????????tp.x=now.x+T*(Rand()+Rand()-0.99);36 ????????????tp.y=now.y+T*(Rand()+Rand()-0.99);37 ????????????double dE=solve(now)-solve(tp);38 ????????????if(dE>0||exp(dE/T)>Rand()) now=tp;39 ????????????T=T*r;40 ????????}41 ????}42 ????For(i,1,5200){43 ????????tp.x=ans.x+T*(Rand()+Rand()-0.99);44 ????????tp.y=ans.y+T*(Rand()+Rand()-0.99);45 ????????solve(tp);46 ????}47 ????printf("%.3lf %.3lf",ans.x,ans.y);48 ????return 0;49 }

P1337 [JSOI2004]平衡点 / 吊打XXX

原文地址:https://www.cnblogs.com/five20/p/9241157.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved