题目大意:在一个周长为10000的圆环上原来有n个平均分布的点,现在要在这个圆环上再增加m个点,并且任然要使这n+m个点均匀分布,所以就要将原来的n个点的位置做一定的移动,以将新来的m个点放进去,现在要求的是,为了把这m个点放进去,要将原来的点移动的距离的和的最小值是多少?
解题报告:,如图,列举了三种情况,黑色的线段表示原有的点的位置,空心的园表示增加m个点之后所有的点的分布,由图中可以看出不管怎么移动,也不管是哪种情况,一定有一个原来的点是不用移动的,所以我们就用这个点作为坐标的原点,其它的点的坐标也就知道了,所以接下俩只要为每一个原来的点(除了那个不要移动的点)找出离它最近的那个空心的圆环就可以了,然后把那些距离加起来就是了。

1 #include<cstdio> 2 #include<algorithm> 3 #include<cmath> 4 const int MAXS=10000+5; 5 6 double MIN(double a,double b) { 7 return a>b? b:a; 8 } 9 int main() { 10 int n,m; 11 while(scanf("%d%d",&n,&m)!=EOF) { 12 if(m%n==0) { 13 printf("0.0\n"); 14 continue; 15 } 16 double old[MAXS]={0},New[MAXS]={0},tot=0,dis1=10000.0/n,dis2=10000.0/(n+m); 17 for(int i=1;i<n;++i) 18 old[i]+=old[i-1]+dis1; 19 for(int i=1;i<m+n-1;++i) 20 New[i]+=New[i-1]+dis2; 21 int z=1; 22 for(int i=1;i<=n;++i) { 23 double min=99999; 24 for(int j=z;;++j) { //求出第i个原有的雕塑应该移到什么位置 25 double x=fabs(old[i]-New[j]); 26 if(x<dis2) { 27 z=j; 28 min=MIN(x,dis2-x); 29 break; 30 } 31 } 32 tot+=min; 33 } 34 printf("%.4lf\n",tot); 35 } 36 return 0; 37 }