UVa1388 - Graveyard

题意:初始把n个纪念碑均匀放在周长为10000的类似圆形的边界上,后来增加m个 纪念碑,问将n+m个纪念碑均匀放置,问原来的n个纪念碑总共最小移动距离

思路:如果先将n个纪念碑当作初始状态,而将n+m个纪念碑作为最终状态,因为中间其它的纪念碑的变化状态多,比较复杂。可以反过来思考,将n+m个纪念碑作为起始状态,而将n个纪念碑作为最终状态,并且假设周长为n+m,这样每个纪念碑都是在坐标为整数的位置,可以计算出n个纪念碑的位置,接着可以根据四舍五入来得到每个纪念碑的最小移动距离,累加起来就是结果。注意,假设起始状态和最终状态始终起点是一样的,即最少有一个点是不动的

代码如下:

#include 
#include 
#include 
#include 

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;
}


你可能感兴趣的:(训练指南,OJ)