在一个周长为10000的圆上等距分布着n个雕塑。现在又有m个新雕塑加入(位置可以随意放),希望所有n+m个雕塑在圆周上均匀分布。这就需要移动其中一些原有的雕塑。要求n个雕塑移动的总距离尽量小。
【输入格式】
输入包含若干组数据。每组数据仅一行,包含两个整数n和m(2≤n≤1 000,1≤m ≤1 000),即原始的雕塑数量和新加的雕塑数量。输入结束标志为文件结束符(EOF)。
【输出格式】
输入仅一行,为最小总距离,精确到10-4。
【样例输入】
2 1
2 3
3 1
10 10
【样例输出】
1666.6667
1000.0
1666.6667
0.0
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n, m;
while (cin>>n>>m)
{
double ans = 0;
for (int i = 1; i<n; i++)
{
double pos = (double)i / n * (n+m);//计算每个需要移动的雕塑的坐标
ans += fabs(pos - floor(pos + 0.5)) / (n+m);//累加移动距离
}
printf("%.4lf\n", ans * 10000);//等比例扩大坐标
}
}
核心代码才两行,但是这思想的确碉堡,一般人写不出这样的东西来,我也不是刚玩ACM的,HDU也刷了300+道题,看到这样的做法还是觉得很吊。
这道题的解法里面有个问题,就是忽略了有两个雕塑抢一个点的问题,这个问题书上也没有给出很正式的证明,但是明确了没有。我们可以这样考虑,现在4个点在圆上,标号1,2,3,4,他们之间的距离我叫它为一个单位,现在有一个雕塑要插入,圈上标号变成ABCDE,雕塑1默认放在A点,当雕塑2通过四舍五入抢占了B点之后,雕塑3绝不会抢占B点,因为雕塑2抢占了,说明雕塑2原来就处于离B点近的位置,这个离B点近的位置加上一个单位,也就是雕塑3没移动的位置,肯定会把雕塑3的位置定在离C点近,而远离了B点,四舍五入之后抢的是C点。
该博客介绍了POJ 3154问题,涉及如何在圆周上均匀分布雕塑,使得移动原有雕塑的总距离最小。博主分享了一个仅两行的精妙代码解决此问题,并讨论了代码中处理雕塑抢占位置的巧妙逻辑。虽然博主有丰富的ACM解题经验,但仍对这种创新解法表示赞赏。

1409

被折叠的 条评论
为什么被折叠?



