题意:初始把n个纪念碑均匀放在周长为10000的类似圆形的边界上,后来增加m个 纪念碑,问将n+m个纪念碑均匀放置,问原来的n个纪念碑总共最小移动距离
思路:如果先将n个纪念碑当作初始状态,而将n+m个纪念碑作为最终状态,因为中间其它的纪念碑的变化状态多,比较复杂。可以反过来思考,将n+m个纪念碑作为起始状态,而将n个纪念碑作为最终状态,并且假设周长为n+m,这样每个纪念碑都是在坐标为整数的位置,可以计算出n个纪念碑的位置,接着可以根据四舍五入来得到每个纪念碑的最小移动距离,累加起来就是结果。注意,假设起始状态和最终状态始终起点是一样的,即最少有一个点是不动的
代码如下:
#include <iostream>
#include <fstream>
#include <cmath>
#include <iomanip>
using namespace std;
const double PERIMETER = 10000;
class Graveyard
{
public:
double calDis(int n, int m)
{
double dis = 0;
for (int i = 1; i < n; i++)
{
double location = (double)i / n * (n + m);
dis += fabs(location - floor(location + 0.5)) / (n + m);
}
return dis * PERIMETER;
}
};
Graveyard solution;
int main()
{
#ifndef ONLINE_JUDGE
ifstream fin("f:\\OJ\\uva_in.txt");
streambuf *old = cin.rdbuf(fin.rdbuf());
#endif
int n, m;
while (cin >> n >> m)
{
cout << fixed << setprecision(4) << solution.calDis(n, m) << endl;
}
#ifndef ONLINE_JUDGE
cin.rdbuf(old);
#endif
return 0;
}