小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,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
输出
100
解析:该题目放的规律比较明显,要想获得最大的疯狂值,先给数组排序,然后把最大的放中间,两边放最小的,然后两边放次大的,然后两边再放次小的…
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Scanner;
public class Main {
//5 10 25 25 40
//25-10-40-5-25
public static int getMaxCrazy(int []arr,int n){
Arrays.sort(arr);
LinkedList<Integer> queue = new LinkedList<>();
queue.add(arr[n-1]);
int low=0;
int high=n-2;
int count=n-1;//剩余需要取得数
int index=0;//奇偶交替放大小的数
if((n-1)%2==0){//剩余的数是偶数个
for(int i=0;i<(n-1)/2;i++){
if(index%2==0){//取最小的两个数
int min1 =arr[low++];
int min2=arr[low++];
int first=queue.getFirst();
int last =queue.getLast();
int sum1=Math.abs(first-min1)+Math.abs(last-min2);
int sum2=Math.abs(first-min2)+Math.abs(last-min1);
if(sum1>sum2){
queue.addFirst(min1);
queue.addLast(min2);
}else{
queue.addFirst(min2);
queue.addLast(min1);
}
index++;
}else{//取两个次大的数
int max1 =arr[high--];
int max2=arr[high--];
int first=queue.getFirst();
int last =queue.getLast();
int sum1=Math.abs(first-max1)+Math.abs(last-max2);
int sum2=Math.abs(first-max2)+Math.abs(last-max1);
if(sum1>sum2){
queue.addFirst(max1);
queue.addLast(max2);
}else{
queue.addFirst(max2);
queue.addLast(max1);
}
index++;
}
}
}else{
//count=3
//5 10 25 40
//25-10-40-5
for(int i=0;i<(n-1)/2+1;i++){
if(index%2==0){//取小的数
if(count-2>=0){//一次放两个
int min1 =arr[low++];
int min2=arr[low++];
int first=queue.getFirst();
int last =queue.getLast();
int sum1=Math.abs(first-min1)+Math.abs(last-min2);
int sum2=Math.abs(first-min2)+Math.abs(last-min1);
if(sum1>sum2){
queue.addFirst(min1);
queue.addLast(min2);
}else{
queue.addFirst(min2);
queue.addLast(min1);
}
index++;
count-=2;
}else{//一次放一个
int min1 =arr[low++];
int first=queue.getFirst();
int last =queue.getLast();
int sum1=Math.abs(first-min1);
int sum2=Math.abs(last-min1);
if(sum1>sum2){
queue.addFirst(min1);
}else{
queue.addLast(min1);
}
index++;
count-=1;
}
}else{
if(count-2>=0){//一次放两个
int max1 =arr[high--];
int max2=arr[high--];
int first=queue.getFirst();
int last =queue.getLast();
int sum1=Math.abs(first-max1)+Math.abs(last-max2);
int sum2=Math.abs(first-max2)+Math.abs(last-max1);
if(sum1>sum2){
queue.addFirst(max1);
queue.addLast(max2);
}else{
queue.addFirst(max2);
queue.addLast(max1);
}
index++;
count-=2;
}else{//一次放一个
int max1 =arr[high--];
int first=queue.getFirst();
int last =queue.getLast();
int sum1=Math.abs(first-max1);
int sum2=Math.abs(last-max1);
if(sum1>sum2){
queue.addFirst(max1);
}else{
queue.addLast(max1);
}
index++;
count-=1;
}
}
}
}
List<Integer> list = new ArrayList<>(queue);
int max=0;
for(int i=1;i<list.size();i++){
max+=Math.abs(list.get(i)-list.get(i-1));
}
int temp=queue.pop();//需要检测队首的元素放在队尾的情况,不然只能通过90%
queue.addLast(temp);
list = new ArrayList<>(queue);
int max2=0;
for(int i=1;i<list.size();i++){
max2+=Math.abs(list.get(i)-list.get(i-1));
}
return Math.max(max, max2);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNextLine()){
int n =sc.nextInt();
int [] arr= new int[n];
for(int i=0;i<n;i++){
arr[i]=sc.nextInt();
}
System.out.println(getMaxCrazy(arr, n));
}
}
}