华为OD机试 - 箱子之字形摆放问题详解及C++/Java/JavaScript/Python代码实现

华为OD机试 - 箱子之字形摆放问题详解及C++/Java/JavaScript/Python代码实现

在华为OD机试中,箱子之字形摆放问题是一个经典的数组处理和模拟算法问题。它不仅考察了对二维数组的操作能力,还涉及到字符串的处理与数据结构的设计。本文将对该题目进行详细解析,并提供C++、Java、JavaScript和Python四种语言的实现。希望通过本文,读者能够全面理解题目的解题思路,熟悉多种编程语言的实现技巧。

一、题目描述

1.1 题目背景

我们有一批箱子,用一个字符串来表示每个箱子上的编号。我们需要将这些箱子按照之字形顺序摆放在宽度为n的空地上,并输出它们的摆放位置。之字形摆放要求每行的箱子是交替从左到右,或者从右到左摆放的,形成类似“Z”字形的排列。

1.2 输入描述

输入只有一行字符串,格式为:

str n

其中,str是表示箱子的字符串,n是空地的宽度,表示摆放箱子的行数。箱子的字符串由字母和数字组成,n是正整数。

1.3 输出描述

按照题目要求,输出最终的箱子摆放结果。每行输出一组摆放好的箱子,并且不应该输出多余的空行。

1.4 输入输出示例

示例 1

输入:

ABCDEFG 3

输出:

AFG
BE
CD

解释:箱子从左到右摆放,宽度为 3,因此可以理解为第一行顺序排,第二行从右往左,第三行再从左往右,依次交替摆放。

示例 2

输入:

HELLOWORLD 4

输出:

HOD
ELW
LOR
L

二、解题思路

2.1 思路分析

为了正确地按照之字形摆放箱子,我们可以将这个问题分解为以下几个步骤:

  1. 初始化矩阵:根据宽度 n,创建一个二维数组(列表/向量),每一行用于存放按照之字形摆放的字符。

  2. 确定每个字符的位置:通过遍历字符串中的每个字符,使用行索引来确定字符应该放置在哪一行。之字形的规律可以通过如下方式进行判断:

    • 如果当前字符应该从左往右摆放,则按照正常顺序填充。
    • 如果当前字符应该从右往左摆放,则需要将字符放置在倒数位置。
  3. 交替顺序控制:通过对当前字符的索引值进行模运算,判断当前行是需要从左到右还是从右到左摆放。可以通过一个标志位来控制当前行的摆放方向。

  4. 输出矩阵:最后将每一行的字符拼接成字符串输出。

2.2 行索引的控制公式

摆放顺序的规律可以通过分析字符位置和行索引的关系总结如下:

  • 行索引公式:i % n,其中 i 表示当前字符的位置。
  • 如果当前列是从左到右,则直接使用 i % n
  • 如果当前列是从右到左,则计算方式为 n - 1 - (i % n)

2.3 算法步骤总结

  1. 初始化一个二维列表(或向量),其长度为 n,每个元素用于存储该行的箱子编号。
  2. 逐个遍历字符串中的字符,计算字符应放置的行索引,并根据之字形的规律进行排列。
  3. 最后按行输出结果。

三、代码实现

3.1 C++ 代码实现

#include <iostream>
#include <vector>
#include <string>
using namespace std;

int main() {
    string str;
    int n;
    cin >> str >> n;
    
    // 创建一个二维向量用于存储箱子摆放结果
    vector<vector<char>> matrix(n);
    
    bool reverse = true;  // 控制之字形顺序的标志位
    for (int i = 0; i < str.length(); i++) {
        int k = i % n;  // 计算字符应放置的行索引
        if (k == 0) reverse = !reverse;  // 每次从新行开始改变摆放顺序
        if (reverse) k = n - 1 - k;  // 若从右到左摆放,则调整索引
        matrix[k].push_back(str[i]);  // 将字符放入对应行
    }
    
    // 输出结果
    for (const vector<char>& list : matrix) {
        for (char character : list) {
            cout << character;
        }
        cout << endl;
    }
    return 0;
}

3.2 JavaScript 代码实现

const readline = require("readline");

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

rl.on("line", (input) => {
  const [str, n] = input.split(" ");
  const width = parseInt(n);
  const matrix = new Array(width).fill().map(() => []);  // 初始化矩阵
  let reverse = true;  // 交替顺序控制

  for (let i = 0; i < str.length; i++) {
    let row = i % width;
    if (row === 0) reverse = !reverse;  // 每次行变化时,调整顺序
    if (reverse) row = width - 1 - row;  // 若是从右往左摆放,则调整行索引
    matrix[row].push(str[i]);  // 放置箱子
  }

  // 输出摆放结果
  matrix.forEach(row => {
    console.log(row.join(''));
  });
});

3.3 Java 代码实现

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();  // 输入箱子字符串
        int n = scanner.nextInt();  // 输入宽度
        ArrayList<ArrayList<Character>> matrix = new ArrayList<>(n);  // 初始化矩阵

        for (int i = 0; i < n; i++) {
            matrix.add(new ArrayList<>());
        }

        boolean reverse = true;  // 控制之字形摆放顺序
        for (int i = 0; i < str.length(); i++) {
            int row = i % n;
            if (row == 0) reverse = !reverse;  // 改变摆放方向
            if (reverse) row = n - 1 - row;
            matrix.get(row).add(str.charAt(i));
        }

        // 输出矩阵
        for (ArrayList<Character> list : matrix) {
            for (char character : list) {
                System.out.print(character);
            }
            System.out.println();
        }
    }
}

3.4 Python 代码实现

# 读取输入
boxes, width = input().split()
width = int(width)

# 初始化二维数组
matrix = [[] for _ in range(width)]
reverse = True  # 用于控制之字形摆放方向

# 遍历所有的箱子
for i, box in enumerate(boxes):
    row = i % width  # 计算当前箱子应该放在哪一行
    if row == 0:
        reverse = not reverse  # 改变方向
    if reverse:
        row = width - 1 - row  # 如果是从右到左摆放,则计算倒数行
    matrix[row].append(box)  # 将箱子放入矩阵

# 输出结果
for line in matrix:
    print("".join(line))

四、复杂度分析

  • 时间复杂度:所有语言的实现中,我们只需要遍历字符串一次,因此时间复杂度为 O(len(str))。每个字符的操作(如插入、输出)都是常数时间操作,因此整体复杂度是线性的。

  • 空间复杂度:由于需要存储字符串中每个字符的位置,因此空间复杂度也为 O(len(str))。此外,额外的空间开销还包括二维数组的存储,约为 O(n),其中 n 是输入的宽度。

五、总结

通过这道“箱子之字形摆放”的题目,我们练习了如何通过二维数组和索引计算,巧妙实现复杂的字符摆放方式。无论是C++、JavaScript、Java还是Python,核心的思路都是一致的:通过行索引控制字符位置,并交替改变行方向。

在面试或机试中

,这类题目既考察了编程基础,又考验了对于规律的敏感性,掌握这样的题型对于通过华为OD机试非常有帮助。

参考网站:

  • 华为OD官方考试页面
  • CSDN相关题目解析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

m0_57781768

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值