题目描述
小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,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
这道题目有一定的难度,使用贪心的策略,一个最大值,一个最小值,依次的加入答案,这里不需要输出对应得答案数组,只需要给出答案,所以每次维护两个变量,一个是当前最大值,一个是当前最小值。
思路:先将height排序,每一次取出最小值和最大值放在队列中
然后再取出最小值和最大值,最小值放在上次最大值的右边
最大值放在上次最小值的左边
Note:需要判断输入个数的奇偶性,若是奇数,最后一个元素
是防止在队头或者队尾,需要和当前的队头和队尾元素比较
eg1: 25-10-40-5-25(n为奇数)
sort:5-10-25-25-40
第一次取出min=5,max=40 queue:[5,40]
第二次取出min=10,max=25 queue:[25,5,40,10]
第三次取出25,放在队头or队尾?明显放在队尾差异更大 queue:[25,5,40,10,25]
res = 20+35+30+15=100
eg2:1-2-4-8-6-10(n为偶数)
sort:1-2-4-6-8-10
第一次取出min=1,max=10 queue:[1,10]
第一次取出min=2,max=8 queue:[8,1,10,2]
第一次取出min=4,max=6 queue:[4,8,1,10,2,6]
res = 4+7+9+8+4=32
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int N = 1000;
int num[N];
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>num[i];
}
int res = 0, left = 1, right = n-2;
sort(num,num+n);
int max_value = num[n-1];
int min_value = num[0];
res+=abs(num[0]-num[n-1]);
while(left<=right){
if(left==right){
// 此时只有一个元素
res+=max(abs(num[left++]-max_value),abs(num[right--]-min_value));
}
else{
res+=abs(num[left]-max_value);
res+=abs(num[right]-min_value);
max_value = num[right--];
min_value = num[left++];
}
}
cout<<res<<endl;
system("pause");
}