P1337 [JSOI2004]平衡点 / 吊打XXX

题目描述

如图:有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:

3
0 0 1
0 2 1
1 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 }

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

时间: 2024-10-09 14:35:56

P1337 [JSOI2004]平衡点 / 吊打XXX的相关文章

P1337 [JSOI2004]平衡点 吊打XXX - 模拟退火

P1337 [JSOI2004]平衡点 吊打XXX 模拟退火 初始温度\(T_0\) 终止温度\(T_k\) 温度变化率\(d\) \(T_k\)略大于0,\(d\)略小于1 当前状态\(x,y\) 当前解\(E\) 当前最优解\(minE\) 当前温度\(T\) 新状态\(nx,ny\) 新解\(nE\) 新解与当前解差值\(\Delta E = nE-E\) \(if\)新解比当前解更优\(nE<E\) 当前状态\(x,y\)移动到 \(nx,ny\) 当前解\(E\)移动到\(nE\) $

洛谷P1337 【[JSOI2004]平衡点 / 吊打XXX】(模拟退火)

洛谷题目传送门 很可惜,充满Mo力的Mo拟退火并不是正解.不过这是一道最适合开始入手Mo拟退火的好题. 对模拟退火还不是很清楚的可以看一下 这道题还真和能量有点关系.达到平衡稳态的时候,物体的总能量应该是最小的.而总的能量来源于每个物体的重力势能之和.要想让某个物体势能减小,那就让拉着它的绳子在桌面下方的长度尽可能的长,也就是桌面上的要尽可能短.由此看来,某个物体的势能与桌面上的绳子的长度.物体重量都成正比. 于是,为了找到平衡点,我们要找一个点使得\(\sum_{i=1}^n d_i*w_i\

[luogu1337][bzoj3680][JSOI2004]平衡点 / 吊打XXX

题目描述 gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将n个gty吊在n根绳子上,每根绳子穿过天台的一个洞.这n根绳子有一个公共的绳结x.吊好gty后蒟蒻们发现由于每个gty重力不同,绳结x在移动.蒟蒻wangxz脑洞大开的决定计算出x最后停留处的坐标,由于他太弱了决定向你求助. 不计摩擦,不计能量损失,由于gty足够矮所以不会掉到地上. 分析 人生中第一道模拟退火题目,感觉模拟退火这个算法非常的优美又非常的(粗鄙之

[JSOI2004]平衡点 / 吊打XXX

考虑模拟退火. 题目要我们找到一个点,使得整个系统平衡. 这个要求等价于让我们找到一个点,使得系统总能量最小. 我们退火出一个点,然后计算其能量即可. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<cstdlib> 7 #include<cmath>

吊打XXX

3680: 吊打XXX Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 2670  Solved: 984[Submit][Status][Discuss] Description gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将 n个gty吊在n根绳子上,每根绳子穿过天台的一个洞.这n根绳子有一个公共的绳结x.吊好gty后蒟蒻们发现由

【BZOJ3680】吊打XXX 模拟退火

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

BZOJ 3680: 吊打XXX【模拟退火算法裸题学习,爬山算法学习】

3680: 吊打XXX Time Limit: 10 Sec  Memory Limit: 128 MBSec  Special JudgeSubmit: 3192  Solved: 1198[Submit][Status][Discuss] Description gty又虐了一场比赛,被虐的蒟蒻们决定吊打gty.gty见大势不好机智的分出了n个分身,但还是被人多势众的蒟蒻抓住了.蒟蒻们将 n个gty吊在n根绳子上,每根绳子穿过天台的一个洞.这n根绳子有一个公共的绳结x.吊好gty后蒟蒻们发现

【BZOJ3680】吊打XXX(模拟退火)

[BZOJ3680]吊打XXX(模拟退火) 题面 BZOJ 题解 模拟退火... 就是模拟退火 然后这题有毒 各种调参数之后终于\(AC\)了.. 这种题就是玄学呀... 温度要调大 最后跑完还要向四周多\(rand\)几次 保证能够找到最优解... #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<

BZOJ 3680 吊打XXX

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