首页 > 试题广场 >

疯狂队列

[编程题]疯狂队列
  • 热度指数:19400 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,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
代码如下:
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;
int main()
{
    int n;
    while(cin >> n){
        vector<int> vec(n);
        for(auto& v:vec) cin >> v;
        sort(vec.begin(),vec.end());
        deque<int> que;       //存储疯狂数列结果
        bool b=false;            //定义取排序偏大的数,还是小数
        int off = 2;                 //大数和小数都连续取两个
        bool fore = true;       //定义放que的前面还是push_back到后面
        int iend = n-2;          //定义大数的游标位置
        int ist = 0;                //定义小数的游标位置
        que.push_back(vec[n-1]);    //先把最大的数放进去
        for(int i=0; i < vec.size()-2; i++){        //只取n-1个数
            if(b){
                if(fore) que.push_front(vec[iend]);
                else que.push_back(vec[iend]);
                iend--;
            }
            else{
                if(fore) que.push_front(vec[ist]);
                else  que.push_back(vec[ist]);
                ist++;
            }
            off --;
            fore = !fore;
            if(off == 0){
                off = 2;
                b = !b;
           }
        }
        int result = 0;
        for(int i=1; i < que.size(); i++) result = result + abs(que[i]-que[i-1]);
        if(abs(que[0]-vec[ist]) > abs(que[que.size()-1] -vec[ist])) cout << result +abs(que[0]-vec[ist]) << endl;
        else cout << result + abs(que[que.size()-1] -vec[ist]) << endl;;
    }
    return 0;
}

发表于 2018-08-05 23:17:03 回复(0)
#include <vector>
#include <algorithm>

using namespace std;

int main() {
	int n;
	cin >> n;
	vector<int> a(n, 0);
	for (int i = 0; i < n; ++i)
		cin >> a[i];
	sort(a.begin(), a.end());
	int i = 0;
	int j = n - 1;
	int ret = abs(a[0] - a[n - 1]);
	while (i <= n / 2 - 2)
		ret += abs(a[i] - a[j - 1]) + abs(a[(i++) + 1] - a[(j--)]);
	if (n % 2 == 1)
        ret += max(abs(a[(n-1)/2-1]-a[(n-1)/2]),abs(a[(n-1)/2+1]-a[(n-1)/2]));
	cout << ret << endl;
	return 0;
}

发表于 2017-08-30 22:05:13 回复(0)
贴一个完美python版的,不用考虑奇偶和其他乱七八糟的也是先排序得到 l,设一个空列表temp=[l[0]],即把最小值放第一个,初始状况left=1指向第二个,right=n-1指向最后一个,然后分四种情况,分别是l[left]和temp[0],l[left]和temp[-1],l[right]和temp[0],l[right]和temp[-1]比较,取差的绝对值最大的一组加进temp,如何是取到了left,就把left右移,取到right,就把right左移,直到left>right为止,最后在temp里求差(也可以在不用这一步,不过能说的清晰一些)
n = int(input())
l = list(map(int,input().split()))

l.sort()
temp =[l[0]]
left = 1
right = n-1
res = 0
while left<=right:
    r0 = abs(temp[0] - l[right])
    lr = abs(temp[-1] - l[right])
    l0 = abs(temp[0]-l[left])
    l1 = abs(temp[-1]-l[left])
    tl = [r0,lr,l0,l1]
    m = max(tl)
    if tl.index(m)==0:
        temp.insert(0,l[right])
        right-=1
    if tl.index(m)==1:
        temp.append(l[right])
        right-=1
    if tl.index(m)==2:
        temp.insert(0,l[left])
        left+=1
    if tl.index(m)==3:
        temp.append(l[left])
        left+=1


for i in range(n-1):
    res+=abs(temp[i+1]-temp[i])
print(res) 


编辑于 2017-08-13 21:01:03 回复(1)
//又是找规律,例子中两个25感觉就是个坑,就是先放入大的,大的两边放小的,然后在次大的,然后......
#include <iostream>
#include <algorithm>
#include <deque>
using namespace std;

void Judge(deque<int> &arr,deque<int> &result, int i)
{
	if(i%2 == 0)
	{
		result.push_back(arr[0]);
		arr.pop_front();
		//这里如果不加判断,则如1 1 1 1 1 1 1 500 500 500 500 1000 1000 1000 1000就会出错,因为按照顺序来就错啦,所以最后一个需要进行判断;
		if(arr.size() == 1 && (abs(arr[0] - result[0]) < abs(result[result.size() - 1] - arr[0])))
		{
			result.push_back(arr[0]);
		}
		else
			result.push_front(arr[0]);
		arr.pop_front();
	}
	else
	{
		result.push_back(arr[arr.size() - 1]);
		arr.pop_back();
		if(arr.size() == 1 && (abs(arr[0] - result[0]) < abs(result[result.size() - 1] - arr[0])))
		{
			result.push_back(arr[0]);
		}
		else
			result.push_front(arr[arr.size() - 1]);
		arr.pop_back();
	}
}

int main()
{
	deque<int> arr, result;
	int sum = 0;
	int count = 0;
	int input;
	int n;
	cin>>n;
	while(cin>>input)
	{
		arr.push_back(input);
	}
	sort(arr.begin(), arr.end());
	result.push_back(arr[n - 1]);
	arr.pop_back();
	if(n % 2 == 0)
	{
		for(int i = 0; i < (n - 2)/2; i++)
		{
			Judge(arr, result, i);
		}
		result.push_back(arr[0]);
	}
	else
	{
		for(int i = 0; i < (n - 1)/2; i++)
		{
			Judge(arr, result, i);
		}
	}
	for(int i = 1; i < n; i++)
	{
		count = result[i] - result[i - 1]; 
		sum = sum + abs(count);
	}
	cout << sum << endl;
	return 0;
}


编辑于 2017-08-13 21:59:20 回复(0)
本人认为最清晰,最好懂,最直白的讲解了😂😁
运行时间:27ms

占用内存:3568k

""""
思路:先将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
    
"""
n = int(input())
height = list(map(int,input().split()))
height.sort()
min_value = height[0]
max_value = height[-1]
res = abs(max_value-min_value)
# 队头指针
top = 1
# 队尾指针
rear = n-2
while top<=rear:
    # 当n为奇数时,最后一步top==rear
    if top==rear:
        res += max(abs(min_value-height[top]),abs(max_value-height[rear]))
    else:
        # 计算右边差距
        res += abs(max_value-height[top])
        # 计算左边差距
        res += abs(min_value-height[rear])
        # update min and max
        min_value = height[top]
        max_value = height[rear]
    # 移动指针
    top += 1
    rear -=1
print(res)

发表于 2019-05-04 21:05:07 回复(2)
#/usr/bin/env pyhton
#-*- coding:utf-8 -*-

'疯狂队列'

__author__ = 'Liusai'
‘’‘
代码是自己写的,想了好久要不要用分奇偶的方法,后来写了下还是分就比较直观,
主要有两点:1.对于最终拍成的疯狂队列ABABABABABABAB。。。。,某一个人对最终疯狂值的影响只与所站的位置为A类还是B类有关,与具体是哪个A或者B无关(首末除外)2.如果队列的疯狂值再加上
首末两人的疯狂值的差,其总和保持不变(与A、B两个类别中的元素具体怎么排列无关),最后用综合减去首末两项的差值就能得到最终的疯狂值了
’‘’

lenth = int(raw_input(''))
h = map(int,raw_input('').split())
h = sorted(h)

if lenth % 2 == 0:
    h1 = h[:lenth/2]
    h2 = h[lenth/2:]
    result = 2 * sum(h2) - 2 * sum(h1)
    result -= h2[0] - h1[-1]
else:
    h1 = h[ : ( lenth - 1 ) / 2 ]
    h2 = h[ ( lenth + 1) / 2 : ]
    result = 2 * sum(h2) - 2 * sum(h1)
    result -= min((h[(lenth-1)/2] - h1[-1]),(h2[0]-h[(lenth-1)/2]))
print result
发表于 2017-08-23 17:08:58 回复(3)
#include <iostream>
#include <vector>
#include <deque>
#include <algorithm>
using namespace std;

int main()
{
    int n;
    cin>>n;
    vector<int> a;
    for (int i=0;i<n;i++){
        int temp;
        cin>>temp;
        a.push_back(temp);
    }
    sort(a.begin(),a.end());
    deque<int> b;
    int i=0;
    int j=n-1;
    int cnt=0;
    while(i<j){
        if (cnt%2==0 && i<j)
        {
    		b.push_back(a[j--]);
    		b.push_front(a[i++]);}
        else if (cnt%2==1 && i<j)
        {
    		b.push_back(a[i++]);
    		b.push_front(a[j--]);
        }
        cnt++;
    }
    if(i==j)//如果i=j,就是有奇数个的情况
    {
        if(abs(a[i]-b[0])>abs(a[i]-b[n-2])){
            b.push_front(a[i]);}
        else{
            b.push_back(a[i]);}
    }
    int res=0;
    for (int i=1;i<b.size();i++){
        res+=abs(b[i]-b[i-1]);
    }
    cout<<res<<endl;
    return 0;
}

发表于 2017-08-12 23:08:52 回复(0)
//AC代码:
#include<stdio.h>
#include<algorithm>
#include<vector>
#include<math.h>
#include<queue>
using namespace std;
int main(){
    int N,i,a[100];
    //freopen("input.txt","r",stdin);
    while(scanf("%d",&N)!=EOF){
        for(i=0;i<N;i++) scanf("%d",&a[i]);
        vector<int> d(N);
        sort(a,a+N);
        deque<int> Q;
        Q.push_back(a[N-1]);
        int l=0,r=N-2,flag=1;
        while(l<r){
            int cnt=1,a1,a2;
            if(flag==1){
                a1=a[l++];
                if(l<r) a2=a[l++],cnt++;
            }else{
                a1=a[r--];
                if(l<r) a2=a[r--],cnt++;
            }
            if(cnt==1)
                abs(Q.front()-a1)<abs(Q.back()-a1)?Q.push_back(a1):Q.push_front(a1);
            else{
                if(abs(Q.front()-a1)+abs(Q.back()-a2)<abs(Q.front()-a2)+abs(Q.back()-a1)){
                    Q.push_front(a2);
                    Q.push_back(a1);
                }else{
                    Q.push_front(a1);
                    Q.push_back(a2);
                }
            }
            flag=!flag;
        }
        if(l==r) abs(Q.front()-a[l])<abs(Q.back()-a[l])?Q.push_back(a[l]):Q.push_front(a[l]);
        int pre=Q.front(),res=0; Q.pop_front();
        while(!Q.empty()){
            res+=abs(Q.front()-pre);
            pre=Q.front();
            Q.pop_front();
        }
        printf("%d\n",res);
    }
}//双端队列,前插后插,乱搞,过了

发表于 2017-08-23 17:54:54 回复(0)
//血的教训,就算调不出来最后那个bug,也至少得90%,然而考试只过了20%,boom!
//总体思路:先放最大的数,然后两边放最小的数,再两边放次大和次次大的数,
//再两边放小的数...直到放完,最后要检查一下两边的元素位置是否合适,不合适的话移动一下
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
 
int main()
{
    int n;
    while(cin>>n)
    {
        vector<int> a(n);
        for(int i=0;i<n;++i)
            cin>>a[i];
        if(1==n)
        {
            cout<<a[0]<<endl;
            return 0;
        }
 
        sort(a.begin(),a.end());
 
        vector<int> b;
        //b.reserve(n);
 
        b.push_back(a[n-1]);
 
        int left=-1;
        int right=n-1;
 
        int flag=1;
        while(left+1<right)
        {
            if(flag)
            {
                b.insert(b.begin(),a[++left]);
                if(left<right)
                    b.push_back(a[++left]);
            }
            else
            {
                b.insert(b.begin(),a[--right]);
                if(left<right)
                    b.push_back(a[--right]);
            }
            flag^=1;
        }
        //这段代码是检测最后一个元素的放置的位置是否合适,不合适的话移到最前面
        //如果没有这一步检查,只能过90%
        if(abs(b[n-1]-b[n-2])<abs(b[n-1]-b[0]))
        {
            int tmp=b[n-1];
            b.erase(b.end()-1);
            b.insert(b.begin(),tmp);
        }
 
        int h=0;
        for(int i=1;i<n;++i)
        {
            h+=abs(b[i]-b[i-1]);
        }
        cout<<h<<endl;
    }
 
    return 0;
}


编辑于 2017-08-12 18:12:24 回复(4)
核心思想就是贪心:将大数和小数组合,让每个数对内的绝对差尽可能大。
1.对数组进行排序,然后利用双指针left和right分别从排序后的数组两端进行取数;
2.第一次取数,两个元素的排列顺序任意,第二次取数,将大的那个数排在前一个数对中较小数的边上,将小的那个数排在前一个数对中较大数的边上,这样就能够保证每个数对间的绝对差尽可能大。
如果有奇数个元素,那么最后肯定会剩下一个数落单,我们只需要检查这个数放在前一个数对的较大数旁边绝对差大,还是较小数旁边绝对差大即可。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine().trim());
        String[] strArr = br.readLine().trim().split(" ");
        int[] arr = new int[n];
        for(int i = 0; i < n; i++) arr[i] = Integer.parseInt(strArr[i]);
        Arrays.sort(arr);
        int left = 0, right = n - 1;
        int maxValue = arr[right] - arr[left];
        int preMax = arr[right];
        int preMin = arr[left];
        left ++;
        right --;
        while(left < right){
            maxValue += preMax + arr[right] - preMin - arr[left];
            preMin = arr[left];
            preMax = arr[right];
            left ++;
            right --;
        }
        if(left == right) maxValue += Math.max(arr[right] - preMin, preMax - arr[left]);
        System.out.println(maxValue);
    }
}


发表于 2021-02-24 21:58:32 回复(0)

逆向排序,分成较大部分和较小部分。再分奇偶讨论即可。

import math
def solve(nums):
    if len(nums) == 1: return nums[0]
    nums = sorted(nums, reverse=True)
    length = len(nums)
    max_part = nums[0: math.ceil(length / 2)]
    min_part = nums[math.ceil(length / 2):]
    if len(nums) % 2 == 0:
        return 2 * sum(max_part[:-1]) + max_part[-1] - 2 * sum(min_part[1:]) - min_part[0]
    else:
        return 2 * sum(max_part[:-2]) + max_part[-2] + max_part[-1] - 2 * sum(min_part)
编辑于 2019-06-23 20:06:11 回复(0)
Python Solution
while True:
    try:
        n=int(input())
        h=sorted(list(map(int,input().split())))
        Max,Min,res=0,0,0
        if n%2==1:
            while(len(h)>1):
                res+=h[-1]-Min+Max-h[0]
                Min=h.pop(0)
                Max=h.pop(-1)
            res+=max(abs(h[0]-Min),abs(h[0]-Max))
            print(res)
        else:
            while(len(h)>0):
                res+=h[-1]-Min+Max-h[0]
                Min=h.pop(0)
                Max=h.pop(-1)
            print(res)
    except:
        break

发表于 2019-03-20 19:52:22 回复(0)
# 先写出一部分在进行公式推导,可分为长度为偶数和奇数的情况,奇数又可以分为ABAB和BABA的情况
def crazy(n: int, h: [int]) -> int:
    if n == 1:
        return 0
    else:
        h = sorted(h)
        if n%2 == 0:
            return 2*sum(h[n//2+1:]) + h[n//2] - 2*sum(h[:n//2-1]) -h[n//2-1]  # 人数为偶数
        else:
            t1 = 2*sum(h[n//2+1:]) - 2*sum(h[:n//2-1]) - sum(h[n//2-1:n//2+1])  # 人数为奇数,且较小的数在较大的数后面
            t2 = 2*sum(h[n//2+2:]) + sum(h[n//2:n//2+2]) - 2*sum(h[:n//2])   # 人数为奇数,且较大的数在较小的数后面
            return max(t1, t2)

if __name__ == "__main__":
    n = int(input())
    h = list(map(int, input().split()))
    print(crazy(n, h))

发表于 2019-03-19 17:57:14 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    scanf("%d", &n);
    int a[n];
    for(int i=0;i<n;i++)
        scanf("%d", &a[i]);
    sort(a, a+n);
    int Max=a[n-1], Min=a[0], l=1, r=n-2, s=Max-Min;
    while(l<r){
        s += (Max-a[l]) + (a[r]-Min);
        Min = a[l++];
        Max = a[r--];
    }
    s += max(Max-a[l], a[r]-Min);
    printf("%d\n", s);
    return 0;
}

发表于 2020-09-27 13:17:34 回复(0)
import java.util.Arrays;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int n=in.nextInt();
        int[]h=new int[n+1];
        int sum=0;

        for (int i = 1;i<=n ; i++) {
          h[i]=in.nextInt();
          }
        if(n==1) System.out.println(0);
        if(n==2) System.out.println(Math.abs(h[0]-h[1]));
        int tp=n;
        int lp=1;
        Arrays.sort(h);
        int c=0;
        int  flag=1;
        sum=sum+2*h[tp]-h[lp]-h[lp+1];
        tp--;
        for (int i =3;  ; i++) {

                if(i==n+1) break;
                if(flag==1)
                {
                    if(c==2) {flag=0;c=0;tp+=2;}
                    c++;
                    sum=sum+h[tp]-h[lp];
                    lp++;
                    tp--;
                }
                else{
                    if(c==2) {flag=1;c=0;lp-=2;}
                    c++;
                    sum=sum+h[tp]-h[lp];
                    tp--;
                    lp++;
                }

        }
        System.out.println(sum);
    }
}

发表于 2020-05-19 17:32:21 回复(0)
#include <bits/stdc++.h>

using namespace std;

int a[55], mark[55];

deque<int> d;

int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  sort(a, a + n);
  d.push_back(a[n - 1]);
  mark[n - 1] = 1;
  int total = n - 1;
  while(total) {
    int Max = 0, idx = 0;
    for (int i = 0; i < n; i++) {
      if (!mark[i]) {
        int tmp = max(abs(a[i] - d.front()), abs(a[i] - d.back()));
        if (tmp > Max) {
          idx = i;
          Max = tmp;
        }
      }
    }
    mark[idx] = 1;
    total--;
    if (abs(a[idx] - d.front()) > abs(a[idx] - d.back())) {
      d.push_front(a[idx]);
    } else {
      d.push_back(a[idx]);
    }
  }
  int ans = 0;
  for (int i = 1; i < (int)d.size(); i++) {
    ans += abs(d.at(i) - d.at(i - 1));
  }
  cout << ans << "\n";
  return 0;
}

发表于 2020-02-18 23:30:32 回复(0)
 n = int(input())
ls = [int(i) for i in input().split()]
ls.sort()
a = []

if len(ls) % 2 == 0:
    count = 1
    for i in range(len(ls)//2):
        maxNum, minNum = ls.pop(-1), ls.pop(0)
        if count > 0:
            a.append(maxNum)
            a.insert(0, minNum)
        else:
            a.append(minNum)
            a.insert(0, maxNum)
        count = -count

    sum = 0
    for j in range(len(a)-1):
        sum += abs(a[j]-a[j+1])
    print(sum)
else:
    count = 1
    for i in range(len(ls)//2):
        maxNum, minNum = ls.pop(-1), ls.pop(0)
        if count > 0:
            a.append(maxNum)
            a.insert(0, minNum)
        else:
            a.append(minNum)
            a.insert(0, maxNum)
        count = -count
    a1 = a[:]
    a1.append(ls[0])
    a2 = a[:]
    a2.insert(0, ls[0])

    sum1 = 0
    for j in range(len(a1)-1):
        sum1 += abs(a1[j]-a1[j+1])
    sum2 = 0
    for k in range(len(a2)-1):
        sum2 += abs(a2[k]-a2[k+1])
    print(max(sum1, sum2))


发表于 2019-04-17 10:50:35 回复(0)
while True:
    try:
        n = int(input())
    except:
        break
    h = list(map(int, input().split()))
    h.sort()
    if len(h) < 2:
        print(0)
        continue
    q = [h.pop()]
    flag = 0
    while len(h) > 2:
        if flag == 0:
            h1 = h.pop(0)
            h2 = h.pop(0)
            flag = 1
        else:
            h1 = h.pop()
            h2 = h.pop()
            flag = 0
        if abs(h1 - q[0]) + abs(h2 - q[-1]) > abs(h1 - q[-1]) + abs(h2 - q[0]):
            q.insert(0, h1)
            q.append(h2)
        else:
            q.insert(0, h2)
            q.append(h1)
    if len(h) == 1:
        h1 = h.pop()
        if abs(h1 - q[0]) > abs(h1 - q[-1]):
            q.insert(0, h1)
        else:
            q.append(h1)
    elif len(h) == 2:
        h1 = h.pop()
        h2 = h.pop()
        case1 = abs(h1 - q[0])
        case2 = abs(h1 - q[-1])
        case3 = abs(h2 - q[0])
        case4 = abs(h2 - q[-1])
        case = max(case1, case2, case3, case4)
        if case == case1 or case == case2:
            if case == case1:
                q.insert(0, h1)
            elif case == case2:
                q.append(h1)
            if abs(h2 - q[0]) > abs(h2 - q[-1]):
                q.insert(0, h2)
            else:
                q.append(h2)
        else:
            if case == case3:
                q.insert(0, h2)
            else:
                q.append(h2)
            if abs(h1 - q[0]) > abs(h1 - q[-1]):
                q.insert(0, h1)
            else:
                q.append(h1)
    res = 0
    for i in range(len(q) - 1):
        res += abs(q[i] - q[i+1])
    print(res)

发表于 2019-03-18 01:22:48 回复(0)
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cstring>
#include<vector>
#include<math.h>
using namespace std;
int n;
int h[51];
int main(){
    cin >> n;
    //相邻学生身高差的绝对值组合
    for(int i = 0; i < n; i++){
        cin >> h[i];
    }
    if(n == 1){
        cout << 0 << endl;
        return 0;
    }
    else if(n == 2){
        cout << abs(h[1] - h[0]) << endl;
        return 0;
    }
    //排序
    sort(h, h + n);
    int sum1 = 0;
    int sum2 = 0;
    //n为偶数 只有一种情况
    if(n % 2 == 0){
        int k = n / 2;
        sum1 = h[k];
        for(int i = k + 1; i < n; i++){
            sum1 += 2 * h[i];
        }
        for(int i = 0; i <= k - 2; i++){
            sum1 -= 2 * h[i];
        }
        sum1 -= h[k - 1];
    }
    //n为奇数 有两种情况
    else{
        int k = n / 2;
        for(int i = k + 1; i < n; i++){
            sum1 += 2 * h[i];
        }
        for(int i = 0; i <= k - 2; i++){
            sum1 -= 2 * h[i];
        }
        sum1 -= h[k];
        sum1 -= h[k - 1];
        sum2 = h[k];
        for(int i = k + 2; i < n; i++){
            sum2 += 2 * h[i];
        }
        for(int i = 0; i <= k - 1; i++){
            sum2 -= 2 * h[i];
        }
        sum2 += h[k + 1];
    }
    cout << max(sum1, sum2) << endl;
    return 0;
}

发表于 2019-02-27 10:36:32 回复(0)
// 又是找规律分为 高低高低高,地高低高低;高低高低高低(低高低高低高)3种
import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int[] h = new int[n];
        for(int i = 0; i < n; i++) h[i] = sc.nextInt();
        sc.close();
        int res = 0;
        Arrays.sort(h);
        if(n == 1){System.out.println(h[0]); return;}
        if((n&1) == 0){// 偶数
            int m = n>>1;
            for(int i = 0; i < m; i++) res += (h[i+m] - h[i]);
            res *= 2;
            res -= (h[m] - h[m-1]);
        }
        else{// 奇数
            // 高低高低高,中位数归高,中位数右边的那个数只加一次
            // 低高低高低,中位数归低,中位数左边的那个数只减一次
            int m = n>>1;
            for(int i = 0; i < m; i++) res += (h[i+m+1] - h[i]);
            res *= 2;
            res += h[m-1] - h[m] > h[m] - h[m+1] ? h[m-1] - h[m] : h[m] - h[m+1];
        }
        System.out.println(res);
    }
}
发表于 2019-02-16 11:10:44 回复(0)

热门推荐

通过挑战的用户

查看代码
疯狂队列