疯狂队列

疯狂队列

题目描述
小易老师是非常严厉的,它会要求所有学生在进入教室前都排成一列,并且他要求学生按照身高不递减的顺序排列。有一次,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.*;
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();
        Arrays.sort(h);
        LinkedList<Integer> list=new LinkedList();
        for(int i=0;i<n/2;i++) {
            if (i == 0) {
                list.offerFirst(h[i]);//最小的放到队首
                list.offerLast(h[n - 1 - i]);//最大的放到对末
            } else {
                if (list.getFirst() - list.getLast() > 0) {
                    list.offerFirst(h[i]);
                    list.offerLast(h[n - 1 - i]);
                } else {
                    list.offerFirst(h[n - 1 - i]);//在首部添加
                    list.offerLast(h[i]);//在尾部添加
                }
            }
        }
         if(n%2!=0)
         {
             int t=h[n/2];
             if(list.getFirst()- list.getLast()>0)
             {
                 list.offerLast(t);
             }
             else
             {
                 list.offerFirst(t);
             }
         }
             int sum=0;
             for(int i=0;i<list.size()-1;i++)
             {
                 sum=sum+(Math.abs(list.get(i)-list.get(i+1)));//取绝对值
             }

         System.out.println(sum);
    }
}
/*
1.本文说明如下的知识点:
    LinkedList的基础用法:
    (1)list.add(添加内容到list中)按照顺序输入则按照顺序存储;
    (2)list.offer //在尾部添加元素;
     (3)list.offerLast//从尾部添加元素;
    (4)读出list中的元素for(int i=0;i<list.size();i++)
    {
          System.out.println(list.get(i));
    }
 */

题目解析:

  1. 输入数据;
  2. 排序;
  3. 算法核心:
    (1)首先将最大的和最小的放入队列(此处不建议用数组,数组的位置不好确定);
    (2)取出下一对最大的数和最小的数,将最大的放在最小的一遍,将最小的放在最大的一边;
    (3)以此类推,若是偶数个数字,那么到此完成,如果是奇数个数字,那么最中间的数字处理很重要:需要判断此时队首和对尾的差距,以此决定他的位置。
  4. 进行差值计算;
  5. 求和并输出。
    思路:先将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
    本文参考了如下的博客:
    https://blog.csdn.net/fmuma/article/details/79601438
    https://www.nowcoder.com/questionTerminal/d996665fbd5e41f89c8d280f84968ee1?orderByHotValue=0&commentTags=Python
    第二个经验提供思路,第一个参考代码,到此结束。
    运行结果:在这里插入图片描述在这里插入图片描述
    完 成 !!!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值