题目描述
如图:有n个重物,每个重物系在一条足够长的绳子上。每条绳子自上而下穿过桌面上的洞,然后系在一起。图中X处就是公共的绳结。假设绳子是完全弹性的(不会造成能量损失),桌子足够高(因而重物不会垂到地上),且忽略所有的摩擦。
问绳结X最终平衡于何处。
注意:桌面上的洞都比绳结X小得多,所以即使某个重物特别重,绳结X也不可能穿过桌面上的洞掉下来,最多是卡在某个洞口处。
输入输出格式
输入格式:
文件的第一行为一个正整数n(1≤n≤1000),表示重物和洞的数目。接下来的n行,每行是3个整数:Xi.Yi.Wi,分别表示第i个洞的坐标以及第 i个重物的重量。
输出格式:
你的程序必须输出两个浮点数(保留小数点后三位),分别表示处于最终平衡状态时绳结X的横坐标和纵坐标。两个数以一个空格隔开。
输入输出样例
输入样例#1: 复制
3
0 0 1
0 2 1
1 1 1
输出样例#1: 复制
0.577 1.000
最后稳定的时候能量最低,即它们的总势能最低,那么我们用退火模拟每次去寻找最优解;
先选定一个温度T;
然后随机变化,幅度为T;
计算新解和当前解谁最优;
如果更优,替换;
否则以exp( -delt/T )替换新解;
参数的选择就可能比较玄学。。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 1000005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define Mod 999911659
#define sq(x) (x)*(x)
#define eps 1e-15
const int N = 2500005;
inline int rd() {
int x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
struct node {
double x, y, w;
}thg[maxn];
int n;
double ansx, ansy;
double cal(double x, double y) {
double tot = 0;
for (int i = 1; i <= n; i++) {
double deltx = x - thg[i].x;
double delty = y - thg[i].y;
tot += sqrt(deltx*deltx + delty * delty)*thg[i].w;
}
return tot;
}
void Test() {
double Tmp = 200.0;
while (Tmp > eps) {
double nowx = ansx + (rand() * 2 - RAND_MAX)*Tmp;
double nowy = ansy + (rand() * 2 - RAND_MAX)*Tmp;
double delt = cal(nowx, nowy) - cal(ansx, ansy);
if (delt < 0)ansx = nowx, ansy = nowy;
else if (exp(-delt / Tmp)*RAND_MAX > rand())ansx = nowx, ansy = nowy;
Tmp *= 0.998;
}
}
int main()
{
//ios::sync_with_stdio(false);
srand((int)time(NULL));
n = rd();
for (int i = 1; i <= n; i++) {
scanf("%lf%lf%lf", &thg[i].x, &thg[i].y, &thg[i].w);
ansx += thg[i].x; ansy += thg[i].y;
}
ansx /= (double)n; ansy /= (double)n;
Test();
printf("%.3lf %.3lf\n", ansx, ansy);
return 0;
}