小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,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:
5
5 10 25 40 25
输出例子1:
100
这题的解法就是一大一小交错着放,最大和最小的先放在一起,然后次大的和次小的再放到两侧,一次类推,可以利用双端队列来解题:
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.Scanner;
public class Test {
static int[] arr;
static boolean[] visited;
static Deque<Integer> deque;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int num = in.nextInt();
arr = new int[num];
visited = new boolean[num];
for (int i = 0; i < num; i++) {
arr[i] = in.nextInt();
visited[i] = false;
}
Arrays.sort(arr);
boolean isForwardDirection = false;
deque = new ArrayDeque<>();
int[] temp = new int[2];
do {
temp[0] = getHigh();
temp[1] = getLow();
int height = isForwardDirection ? 0 : 1;
int low = isForwardDirection ? 1 : 0;
if (temp[height] != -1){
deque.addFirst(temp[height]);
}
if (temp[low] != -1){
deque.addLast(temp[low]);
}
isForwardDirection = !isForwardDirection;
}while (temp[0] != -1 || temp[1] != -1);
int sum = 0;
System.out.println(Arrays.toString(deque.toArray()));
Object[] result = deque.toArray();
for (int i = 0; i < result.length - 1; i++) {
sum += Math.abs(((Integer) result[i] - ((Integer) result[i + 1])));
}
System.out.println(sum);
}
public static int getHigh() {
for (int i = arr.length - 1; i >= 0; i--) {
if (!visited[i]) {
visited[i] = true;
return arr[i];
}
}
return -1;
}
public static int getLow() {
for (int i = 0; i < arr.length; i++) {
if (!visited[i]) {
visited[i] = true;
return arr[i];
}
}
return -1;
}
}