UVA_10041

这个题目是一个贪心的题目。

如果设按升序排列的si的数组为s[],那么Vito的位置一定为s[(r-1)/2]。对于这一点,我们分两种情况进行讨论:

①如果si的数量为奇数,那么Vito的位置一定取数组s[]中间的那个值s[(r-1)/2]。因为如果周围的值和s[(r-1)/2]相同的话,Vito的位置左右移动不会产生影响,但如果周围的某个值s[i]不和s[(r-1)/2]相同,倘若Vito的位置移到了这个值上面,可以计算得出,总距离至少增加了abs(s[i]-s[(r-1)/2])(如果s[i]不和s[(r-1)/2]紧邻的话,会增加的更多)

    ②如果si的数量为偶数,那么Vito的位置可以是[ s[(r-1)/2] , s[(r-1)/2+1] ]这个闭区间中的任意一个值。这点我们同样可以用反证法进行证明。

之后便只需要将所有的距离加起来即可。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int s[510];
int cmp(const void *_p,const void *_q)
{
int *p=(int *)_p;
int *q=(int *)_q;
return *p-*q;
}
int main()
{
int i,j,k,t,r,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&r);
for(i=0;i<r;i++)
scanf("%d",&s[i]);
qsort(s,r,sizeof(s[0]),cmp);
k=s[(r-1)/2];
sum=0;
for(i=0;i<r;i++)
sum+=abs(s[i]-k);
printf("%d\n",sum);
}
return 0;
}


posted on 2011-09-21 22:17  Staginner  阅读(548)  评论(0编辑  收藏  举报