> 技术文档 > 华为OD机考2025C卷 - 数字螺旋矩阵 (C++ & Python & JAVA & JS & GO)

华为OD机考2025C卷 - 数字螺旋矩阵 (C++ & Python & JAVA & JS & GO)


数字螺旋矩阵

华为OD机试真题目录点击查看: 华为OD机试2025C卷真题题库目录|机考题库 + 算法考点详解

华为OD机试 2025C卷 100分题型

题目描述

疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:
给出数字个数n和行数m(0 < n ≤ 999,0 < m ≤ 999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出2,3…n,最终形成一个m行矩阵。
小明对这个矩阵有些要求:

  • 每行数字的个数一样多
  • 列的数量尽可能少
  • 填充数字时优先填充外部
  • 数字不够时,使用单个*号占位

输入描述

输入一行,两个整数,空格隔开,依次表示n、m

输出描述

符合要求的唯一矩阵

示例1

输入

9 4

输出

1 2 3* * 49 * 58 7 6

说明

9个数字写成4行,最少需要3列

示例2

输入

3 5

输出

123**

说明

3个数字写5行,只有一列,数字不够用*号填充

示例3

输入

120 7

输出

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 1846 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 1945 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 63 2044 83 114 115 116 117 118 119 120 * * * * * * 99 64 2143 82 113 112 111 110 109 108 107 106 105 104 103 102 101 100 65 2242 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 2341 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24

题解

思路: 模拟

  • 根据输入的n m 来计算出需要的列col = (num + m -1) / m, 向上取整。
  • 定义个matrix[m][col]数组初始的话可以将数组所有元素默认设置为0,然后按照螺旋的方式将数字添入数组中就行,一直循环直到填充完num个数。具体模拟逻辑如下:
    • 可以定义top bottom left right 代表本次循环的四个边界
    • 根据规律螺旋过程对应四次转弯,发生在碰到对应边界时,并更新对应需要的边界范围。
      • 初始从左至右,碰到右边界,更新上边界范围。转向从上到下
      • 碰到下边界时,更新右边界,转向从右至左。
      • 碰到左边界时,更新下边界,转向从下到上。
      • 碰到上边界时,更新左边界,转向从左至右。
    • 重复上述逻辑直到将n个数全部填充完毕为止。
  • 执行完上述填充操作之后,按行进行输出填充后的数组,对应位置为0输出*

c++

#include #include #include int main() { int n, m; std::cin >> n >> m; // 读取 n 和 m int cols = (n + m - 1) / m; // 计算列数 向上取整 std::vector<std::vector<int>> matrix(m, std::vector<int>(cols)); // 定义矩阵 int num = 1, top = 0, bottom = m - 1, left = 0, right = cols - 1; while (num <= n) { for (int i = left; i <= right && num <= n; i++) matrix[top][i] = num++; // 从左到右 top++; for (int i = top; i <= bottom && num <= n; i++) matrix[i][right] = num++; // 从上到下 right--; for (int i = right; i >= left && num <= n; i--) matrix[bottom][i] = num++; // 从右到左 bottom--; for (int i = bottom; i >= top && num <= n; i--) matrix[i][left] = num++; // 从下到上 left++; } std::ostringstream output; for (int i = 0; i < m; i++) { for (int j = 0; j < cols; j++) { if (matrix[i][j] == 0) { output << \'*\'; } else { output << matrix[i][j]; } if (j < cols - 1) output << \' \'; // 避免末尾多余空格 } output << \'\\n\'; // 换行 } std::cout << output.str(); // 一次性输出,提高性能 return 0;}

Java

import java.util.Scanner;public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); // 读取 n int m = scanner.nextInt(); // 读取 m scanner.close(); // 关闭输入流 int cols = (n + m - 1) / m; // 计算列数,向上取整 int[][] matrix = new int[m][cols]; // 定义矩阵 // 初始值 for (int i = 0; i < m; i++) { for (int j = 0; j < cols; j++) { matrix[i][j] = -1; } } int num = 1, top = 0, bottom = m - 1, left = 0, right = cols - 1; while (num <= n) { for (int i = left; i <= right && num <= n; i++) matrix[top][i] = num++; // 从左到右 top++; for (int i = top; i <= bottom && num <= n; i++) matrix[i][right] = num++; // 从上到下 right--; for (int i = right; i >= left && num <= n; i--) matrix[bottom][i] = num++; // 从右到左 bottom--; for (int i = bottom; i >= top && num <= n; i--) matrix[i][left] = num++; // 从下到上 left++; }  // 输出矩阵 StringBuilder output = new StringBuilder(); for (int i = 0; i < m; i++) { for (int j = 0; j < cols; j++) { output.append(matrix[i][j] == -1 ? \"*\" : matrix[i][j]); if (j < cols - 1) output.append(\" \"); // 避免最后一列后多余空格 } output.append(\"\\n\"); } System.out.print(output); // 一次性输出,提高性能 }}

Python

import sysimport math# 读取输入n, m = map(int, sys.stdin.readline().split())cols = (n + m - 1) // m # 计算列数,向上取整matrix = [[0] * cols for _ in range(m)] # 定义矩阵num, top, bottom, left, right = 1, 0, m - 1, 0, cols - 1while num <= n: for i in range(left, right + 1): if num > n: break matrix[top][i] = num num += 1 top += 1 for i in range(top, bottom + 1): if num > n: break matrix[i][right] = num num += 1 right -= 1 for i in range(right, left - 1, -1): if num > n: break matrix[bottom][i] = num num += 1 bottom -= 1 for i in range(bottom, top - 1, -1): if num > n: break matrix[i][left] = num num += 1 left += 1# 输出矩阵output = []for row in matrix: output.append(\" \".join(str(cell) if cell != 0 else \'*\' for cell in row))sys.stdout.write(\"\\n\".join(output) + \"\\n\")

JavaScript

const readline = require(\"readline\");const rl = readline.createInterface({ input: process.stdin, output: process.stdout});rl.on(\"line\", (input) => { const [n, m] = input.split(\" \").map(Number); const cols = Math.ceil(n / m); // 计算列数,向上取整 let matrix = Array.from({ length: m }, () => Array(cols).fill(0)); // 定义矩阵 let num = 1, top = 0, bottom = m - 1, left = 0, right = cols - 1; while (num <= n) { for (let i = left; i <= right && num <= n; i++) matrix[top][i] = num++; // 从左到右 top++; for (let i = top; i <= bottom && num <= n; i++) matrix[i][right] = num++; // 从上到下 right--; for (let i = right; i >= left && num <= n; i--) matrix[bottom][i] = num++; // 从右到左 bottom--; for (let i = bottom; i >= top && num <= n; i--) matrix[i][left] = num++; // 从下到上 left++; } let output = matrix.map(row => row.map(cell => cell === 0 ? \'*\' : cell).join(\" \")).join(\"\\n\"); console.log(output); rl.close();});

Go

package mainimport (\"bufio\"\"fmt\"\"os\"\"strconv\"\"strings\")func main() {// 读取输入reader := bufio.NewReader(os.Stdin)line, _ := reader.ReadString(\'\\n\')fields := strings.Fields(line)n, _ := strconv.Atoi(fields[0])m, _ := strconv.Atoi(fields[1])cols := (n + m - 1) / m // 计算列数,向上取整matrix := make([][]int, m)for i := range matrix {matrix[i] = make([]int, cols)}num, top, bottom, left, right := 1, 0, m-1, 0, cols-1for num <= n {// 右移for i := left; i <= right && num <= n; i++ {matrix[top][i] = numnum++}top++// 下移for i := top; i <= bottom && num <= n; i++ {matrix[i][right] = numnum++}// 左移right--for i := right; i >= left && num <= n; i-- {matrix[bottom][i] = numnum++}bottom--// 上移for i := bottom; i >= top && num <= n; i-- {matrix[i][left] = numnum++}left++}// 输出矩阵var output strings.Builderfor i := 0; i < m; i++ {for j := 0; j < cols; j++ {if matrix[i][j] == 0 {output.WriteString(\"*\")} else {output.WriteString(strconv.Itoa(matrix[i][j]))}if j < cols-1 {output.WriteString(\" \") // 避免末尾空格}}output.WriteString(\"\\n\")}fmt.Print(output.String()) // 一次性输出,提高性能}