被吊打了啊 !
这道题, 看上去真的挺难的 .
简言之, 就是求平衡状态时, 中心点的位置 .
做出受力分析图, 我们可以看得出来, 这个点的位置, 其实与绳子是无关的,
每根绳的拉力, 也一定是等于重物的
所以, 我们可以先随机一个点, 求出这\(n\)根线对着个点的作用力的合力.
因为力的方向不好表示, 所以我们可以正交分解, 将力分解到\(x\)轴和\(y\)轴上去.
这个点必定会沿合力方向移动一定的距离, 直到合力为零.
但是, 我们在不用其他数学工具的情况下, 我们可以随机一个较大步长,
然后不断地缩小这个步长, 就可以越来越接近这个目标点了.
当某一次的移动前后的变化小于精度范围时, 那么我们就找到答案了.
Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include <bits/stdc++.h>
using namespace std;
const int Maxn = 1005; int N; double X, Y; bool Xf(1), Yf(1); struct Node { int X, Y, G; }Points[Maxn];
inline void Solve(double M) { double x(0), y(0), Temp; for (int i = 1; i <= N; ++i) { Temp = sqrt((X - Points[i].X) * (X - Points[i].X) + (Y - Points[i].Y) * (Y - Points[i].Y)); if (!Temp) continue; x += Points[i].G / Temp * (Points[i].X - X); y += Points[i].G / Temp * (Points[i].Y - Y); } Temp = sqrt(x * x + y * y); Y += M / Temp * y; X += M / Temp * x; }
int main() { scanf ("%d", &N); for (int i = 1; i <= N; ++i) scanf ("%d %d %d", &Points[i].X, &Points[i].Y, &Points[i].G);
double M = 10000, tx, ty; while (1) { tx = X, ty = Y; Solve(M); if (abs(tx - X) < 0.00001 && abs(ty - Y) < 0.00001) break; M *= 0.9; } printf ("%.3lf %.3lf\n", X, Y); system ("pause"); }
|