小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,n个学生在列队的时候,小易老师正好去卫生间了。学生们终于有机会反击了,于是学生们决定来一次疯狂的队列,他们定义一个队列的疯狂值为每对相邻排列学生身高差的绝对值总和。由于按照身高顺序排列的队列的疯狂值是最小的,他们当然决定按照疯狂值最大的顺序来进行列队。现在给出n个学生的身高,请计算出这些学生列队的最大可能的疯狂值。小易老师回来一定会气得半死。
输入描述:
输入包括两行,第一行一个整数n(1 ≤ n ≤ 50),表示学生的人数 第二行为n个整数h[i](1 ≤ h[i] ≤ 1000),表示每个学生的身高
输出描述:
输出一个整数,表示n个学生列队可以获得的最大的疯狂值。 如样例所示: 当队列排列顺序是: 25-10-40-5-25, 身高差绝对值的总和为15+30+35+20=100。 这是最大的疯狂值了。
要解决这个题,首先要弄清楚,一个数列要如何排列才能使得相邻元素的差的绝对值之和最大,我们举一个例子:
假设数列是1,2,3,4,5,6,7。我们先取最大的元素7,要绝对值尽可能的大,第二个元素我们取1,这样我们得到了[1,7],
接下来,我们从剩下的元素中取最大值,排放在1的旁边,取最小值排放在7的旁边,这样我们得到了[6,1,7,2]
继续上述过程,从剩下的元素中取最大值放在两侧较小元素的旁边,取最小值放在较大元素的旁边
……
直到最后,我们每次取2个元素,剩余的元素个数可能为0,也可能为1.如果还剩下1个元素,比较一下放在左边和右边的差值绝对值,那边大放哪边就好。
这样一个过程就可以使得一个队列的疯狂值达到最大了。
下面我们使用代码实现这一过程:
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
while(in.hasNext()){
int n = in.nextInt();
in.nextLine();
int[] num = new int[n];
for(int i=0;i<n;i++){
num[i] = in.nextInt();
}
Arrays.sort(num); //排序
if(n==0 || n==1)
System.out.println(0);
if(n == 2)
System.out.println(num[1]-num[0]);
boolean b = false;
if(n>2) b = true;
int start = 1;
int end = n-2;
int max = num[n-1];
int min = num[0];
int abs = num[n-1]-num[0];
while(start <= end){
if(start == end){ //最后剩下1个元素的情况
abs += Math.max(Math.abs(num[start]-min),Math.abs(num[start]-max));
break;
}
int maxt = num[end];
int mint = num[start];
abs += Math.abs(min-maxt);
abs += Math.abs(max-mint);
min = mint;
max = maxt;
start++;
end--;
}
if(b)
System.out.println(abs);
}
}
}