华为OD机试 - 螺旋数字矩阵

1 题目描述

疫情期间,小明隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:

给出数字个数 n (0 < n ≤ 999)和行数 m(0 < m ≤ 999),从左上角的 1 开始,按照顺时针螺旋向内写方式,依次写出2,3,...,n,最终形成一个 m 行矩阵。

小明对这个矩阵有些要求:

每行数字的个数一样多

列的数量尽可能少

填充数字时优先填充外部

数字不够时,使用单个 * 号占位

2 输入描述

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

3 输出描述

符合要求的唯一矩阵

4 用例

4.1 用例1

输入

复制代码
9 4

输出

复制代码
1 2 3
* * 4
9 * 5
8 7 6

4.2 用例2

输入

复制代码
3 5

输出

复制代码
1
2
3
*
*

5 题目分析·

考点 :这道题考的是对二维数组的使用。
解析 :题目中比较容易钻牛角尖的描述是每行数字的个数一样多。这句实际上是矩阵的特点,可以忽略。读完题目,我们发现有两个问题需要解决

复制代码
1. 确定矩阵的列数
2. 设计填充的算法

通过列的数量尽可能少这个需求,我们可以想到,最少的情况,即矩阵中填充的全都是数字。那么列数= 填充的数字个数n/行数向上取整。

然后是如何填充,这就涉及到了二维数组的螺旋形遍历。我们可以想象一个人在背包容量限制下,在顺时针绕圈捡东西,当不为0,则为已捡过,即换方向捡。

6 Java代码

根据5中的思路,我们可以写出如下代码(代码中给出了详细的注释):

java 复制代码
public class SpiralMatrix {
    public static void main(String[] args) {
        //这里n和m可以修改为使用Scanner从控制台读取输入
        int n = 120;
        int m = 7;
        int columnCount=Math.ceilDiv(n,m);
        int[][] matrix = new int[m][columnCount];
        fillSpiral(matrix,n);
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < columnCount; j++) {
                System.out.printf("%2s ", matrix[i][j] == 0 ? "*" : matrix[i][j]);
            }
            System.out.println();
        }
    }

    public static void fillSpiral(int[][] matrix, int total) {
        // 将要填充的数字,从1开始
        int num = 1;
        // 方向变量,四个元素分别表示:向右,向下,向左,向上
        int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
        // 初始化方向变量的索引,0表示初始方向为向右
        int dir = 0;
        // 初始化行列索引
        int row = 0, col = 0;
        // 继续填充,直到所有的数字被填充完
        while (num <= total) {
            // 将数字填充到矩阵的当前位置,然后数字加1
            matrix[row][col] = num++;
            // 尝试按照当前方向去获取新的行列索引
            int newRow = row + directions[dir][0];
            int newCol = col + directions[dir][1];
            // 检查新的行列索引是否超出矩阵的边界,或者该位置已经被填充过
            // 如果是,则将方向变量的索引加1(取模为了形成循环:向右,向下,向左,向上)
            if (newRow < 0 || newRow >= matrix.length || newCol < 0 || newCol >= matrix[0].length || matrix[newRow][newCol] != 0) {
                dir = (dir + 1) % 4;
            }
            // 根据新的方向更新行列索引
            row += directions[dir][0];
            col += directions[dir][1];
        }
    }
}
相关推荐
宇宙之一粟5 小时前
乐企版式文件生成平台
java·后端·python
学测绘的小杨21 小时前
CompassFusion:一个从 GNSS 到 GNSS/INS 组合导航的独立工程包
python
zzzzzz3101 天前
当产品经理说这个很简单:我用Python自动化处理奇葩需求的实战指南
python·pycharm·产品经理
雪隐1 天前
个人电脑玩AI-06让5060 Ti给你打工——不光能画画,Qwen3-TTS还能学人说话,连我老板都信了!
人工智能·后端·python
兵慌码乱2 天前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot2 天前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海2 天前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱2 天前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
曲幽2 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
荣码2 天前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python