(B卷,100分)- 高矮个子排队(Java & JS & Python & C)

题目描述

现在有一队小朋友,他们高矮不同,我们以正整数数组表示这一队小朋友的身高,如数组{5,3,1,2,3}。

我们现在希望小朋友排队,以“高”“矮”“高”“矮”顺序排列,每一个“高”位置的小朋友要比相邻的位置高或者相等;每一个“矮”位置的小朋友要比相邻的位置矮或者相等;

要求小朋友们移动的距离和最小,第一个从“高”位开始排,输出最小移动距离即可。

例如,在示范小队{5,3,1,2,3}中,{5, 1, 3, 2, 3}是排序结果。

{5, 2, 3, 1, 3} 虽然也满足“高”“矮”“高”“矮”顺序排列,但小朋友们的移动距离大,所以不是最优结果。

移动距离的定义如下所示:

第二位小朋友移到第三位小朋友后面,移动距离为1,若移动到第四位小朋友后面,移动距离为2;

输入描述

排序前的小朋友,以英文空格的正整数:

4 3 5 7 8

注:小朋友<100个

输出描述

排序后的小朋友,以英文空格分割的正整数:4 3 7 5 8

备注:4(高)3(矮)7(高)5(矮)8(高), 输出结果为最小移动距离,只有5和7交换了位置,移动距离都是1。

用例

输入 4 1 3 5 2
输出 4 1 5 2 3
说明
输入 1 1 1 1 1
输出 1 1 1 1 1
说明 相邻位置可以相等
输入 xxx
输出 [ ]
说明 出现非法参数情况, 返回空数组。

题目解析

感觉本题的用例1是存在问题的

4 1 3 5 2

的最小移动距离应该是1,即让5和2交换位置,变为:4 1 3 2 5,这样的话,也满足:高 矮 高 矮 高。

而用例输出的逻辑是先让3和5交换,变为 4 1 5 3 2,再让3和2交换,变为 4 1 5 2 3,这样的话也满足:高 矮 高 矮 高,但是却交换了两次,也就是说移动距离是2。

难道说,用例逻辑是,必须要从第一个小朋友开始,每当遇到不符合要求的排队顺序,就必须交换位置吗?

那么题目描述中又为何要强调最小距离呢?

感觉这题有点自相矛盾。

我这里按照符合用例要求的逻辑写的代码,示意图如下

 但是这种算法是不满足最小距离要求的。

JavaScript算法源码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("line", (line) => {
  if (!/(ds)+/.test(line)) return console.log("[]");

  const arr = line.split(" ").map(Number);

  let flag = true;
  for (let i = 0; i < arr.length - 1; i++) {
    if (arr[i] !== arr[i + 1] && arr[i] > arr[i + 1] !== flag) {
      let tmp = arr[i];
      arr[i] = arr[i + 1];
      arr[i + 1] = tmp;
    }

    flag = !flag;
  }
  console.log(arr.join(" "));
});

Java算法源码

import java.util.Arrays;
import java.util.Scanner;
import java.util.StringJoiner;

public class Main {
  // 输入获取
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    try {
      Integer[] arr =
          Arrays.stream(sc.nextLine().split(" ")).map(Integer::parseInt).toArray(Integer[]::new);

      System.out.println(getResult(arr));
    } catch (Exception e) {
      System.out.println("[]");
    }
  }

  // 算法入口
  public static String getResult(Integer[] arr) {
    // i高->i+1矮 为true,i矮->i+1高 为false
    boolean flag = true;

    for (int i = 0; i < arr.length - 1; i++) {
      if (arr[i] != arr[i + 1] && (arr[i] > arr[i + 1]) != flag) {
        int tmp = arr[i];
        arr[i] = arr[i + 1];
        arr[i + 1] = tmp;
      }

      flag = !flag;
    }

    StringJoiner sj = new StringJoiner(" ");
    for (Integer h : arr) {
      sj.add(h + "");
    }
    return sj.toString();
  }
}

Python算法源码

# 算法入口
def getResult(arr):
    flag = True

    for i in range(len(arr) - 1):
        if arr[i] != arr[i + 1] and (arr[i] > arr[i + 1]) != flag:
            tmp = arr[i]
            arr[i] = arr[i + 1]
            arr[i + 1] = tmp

        flag = not flag

    return " ".join(map(str, arr))


# 输入获取
try:
    arr = list(map(int, input().split()))
    print(getResult(arr))
except ValueError:
    print("[]")

C算法源码

#include <stdio.h>
#include <string.h>

#define MAX_SIZE 100

void getResult(int nums[], int nums_size);

int main() {
    int nums[MAX_SIZE];
    int nums_size = 0;

    while(scanf("%d", &nums[nums_size])) {
        nums_size++;
        if(getchar() != ' ') break;
    }

    if(nums_size == 0) {
        puts("[]");
    } else {
        getResult(nums, nums_size);
    }

    return 0;
}

void getResult(int nums[], int nums_size) {
    // i高->i+1矮 为true,i矮->i+1高 为false
    int flag = 1;

    for(int i=0; i<nums_size-1; i++) {
        if(nums[i] != nums[i+1] && (nums[i] > nums[i+1]) != flag) {
            int tmp = nums[i];
            nums[i] = nums[i+1];
            nums[i+1] = tmp;
        }

        flag = !flag;
    }

    char res[MAX_SIZE * 10] = {''};
    for(int i=0; i<nums_size; i++) {
        char tmp[10];
        sprintf(tmp, "%d", nums[i]);
        strcat(res, tmp);

        if(i != nums_size - 1) {
            strcat(res, " ");
        }
    }

    puts(res);
}

免责声明:

1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文

0

评论0

站点公告

没有账号?注册  忘记密码?