校oj题 团团坐

Description

又到了acm实验室半年一次的集训了.ACMers,只觉得整个世界都是程序设计,头晕目眩.

现在实验室有n个队员,围成一圈开早会,汇报学习进度,
他们等间距的分布在圆桌上,圆桌的周长为1000.

这时候大丁突然想起来需要有个人下楼开门.所以决定随机找一个人下去开门.
然后他就一如既往的随机到了小胖学长,小胖说了一句"我笑了",就离开了.

为了继续圆桌会议,大丁决定让剩下的n-1个人,移动位置重新等间距分布.

但是大丁比较惫懒,于是将任务交给了dajiang学长.问他们一共最少需要移动多少距离。
这下可把dajiang给愁坏了.这不,他来请教在座的诸位大佬.

Input

多组测试,每组输入n,1<=n<=1000000000

Output

每组输出一个最小距离,保留整数位

Sample Input 1

1
2
3
4

Sample Output 1

0
0
167
167

解题思路:我一开始做这个的时候,想的是每一个人(除了第一个以外)都往同一个方向移一定的距离,但是不管怎么写,这个题就是WA,最后比赛成绩也不理想。难受得一匹。然后最近看蓝书上的思想体操的时候,对这道题有了新的思路理解,然后我就补了这道题。


书上举例子是UVA的 墓地雕塑。在原有的n个墓碑基础上,添加m个墓碑,然后距离还是平均相等。


我们可以把这道题的思路转化一下,我们可以认为 一开始只有n-1个人,然后添加进来一个,让你求最小的移动距离,这和题目是等价的。我们完全可以这样做。然后就是求每一个人在假定的(n-1)长度上应该在的位置。累加就是答案。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
using namespace std;
const double pos=1e-6;
double ans,a,b;
int n,i;
int main(){
	while(scanf("%d",&n)!=EOF){
		if(n==1||n==2){
			printf("0\n");
			continue;
		}
		if(n>=600){
			printf("250\n");
			continue;
		}
		ans=0;
		for(i=1;i<n;i++){
			double k=(double)i*n/(n-1);
			double t=fabs(k-floor(k+0.5))/(n);
			ans+=t;
		}
		printf("%.0lf\n",ans*1000);
	}
	return 0;
} 


猜你喜欢

转载自blog.csdn.net/bao___zi/article/details/79808667
今日推荐