news 2026/8/29 23:07:30

螺旋数字矩阵 (Java / Python / C++)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
螺旋数字矩阵 (Java / Python / C++)

题目描述

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

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

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

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

输入描述

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

输出描述

符合要求的唯一矩阵

示例1

1

2

3

4

5

6

7

8

9

10

11

输入:

94

输出:

123

* *4

9*5

876

说明:

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

示例2

1

2

3

4

5

6

7

8

9

10

11

12

输入:

35

输出:

1

2

3

*

*

说明:

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

题解

这是一个模拟题,主要考察对矩阵的遍历和填充的能力。

  1. 首先,通过输入获取数字个数n和行数m。
  2. 计算矩阵的列数cols,根据题意,最少需要的列数是(n-1) / m + 1。
  3. 初始化一个大小为m行cols列的矩阵,所有元素初始值为"*"。
  4. 使用四个变量top、bottom、left、right来表示当前矩阵的上下左右边界。
  5. 使用cur变量表示当前要填充的数字,从1开始。
  6. 进入循环,按照顺时针螺旋的方式依次填充矩阵的数字。
    • 从左到右:遍历当前行的左右范围,依次填充数字。
    • 从上到下:遍历当前列的上下范围,依次填充数字。
    • 从右到左:遍历当前行的右左范围,依次填充数字。
    • 从下到上:遍历当前列的下上范围,依次填充数字。
  7. 在每次填充后,更新相应的边界。
  8. 循环直到所有数字都填充完毕。
  9. 最后,输出填充好的矩阵。

这样,通过模拟顺时针螺旋填充的过程,就能得到符合要求的矩阵。

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

importjava.util.Arrays;

importjava.util.Scanner;

importjava.util.stream.Collectors;

/**

* @author code5bug

*/

publicclassMain {

publicstaticvoidmain(String[] args) {

Scanner in =newScanner(System.in);

intn = in.nextInt(), m = in.nextInt();

introws = m, cols = (n -1) / m +1;

// grid[i][j] == 0 则认为数字不够为 *

int[][] grid =newint[rows][cols];

// 上下左右,四侧的边界

inttop =0, bottom = rows -1, left =0, right = cols -1;

intcur =1;

while(cur <= n) {

// 从左到右

for(inti = left; i <= right && cur <= n; i++) {

grid[top][i] = cur++;

}

if(++top > bottom)break;// 收缩范围

// 从上到下

for(inti = top; i <= bottom && cur <= n; i++) {

grid[i][right] = cur++;

}

if(--right < left)break;// 收缩范围

// 从右到左

for(inti = right; i >= left && cur <= n; i--) {

grid[bottom][i] = cur++;

}

if(--bottom < top)break;// 收缩范围

// 从下到上

for(inti = bottom; i >= top && cur <= n; i--) {

grid[i][left] = cur++;

}

if(++left > right)break;// 收缩范围

}

// 输出结果

Arrays.stream(grid)

.map(row -> Arrays.stream(row)

.mapToObj(num -> num ==0?"*": String.valueOf(num))

.collect(Collectors.joining(" ")))

.forEach(System.out::println);

}

}

Python

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

n, m = map(int, input().split())

# 计算需要的列数 cols

rows, cols = m, (n -1)// m + 1

# 初始化矩阵所有值为*

grid = [['*'] * colsfor_ in range(rows)]

# 上下左右,四侧的边界

top, bottom, left, right =0, rows -1,0, cols -1

cur =1

whileTrue:

# 从左到右

fori in range(left, right +1):

ifcur <= n:

grid[top][i] = cur

cur +=1

top +=1# 收缩范围

iftop > bottom:break

# 从上到下

fori in range(top, bottom +1):

ifcur <= n:

grid[i][right] = cur

cur +=1

right -=1# 收缩范围

ifright < left:break

# 从右到左

fori in range(right, left -1, -1):

ifcur <= n:

grid[bottom][i] = cur

cur +=1

bottom -=1# 收缩范围

ifbottom < top:break

# 从下到上

fori in range(bottom, top-1, -1):

ifcur <= n:

grid[i][left] = cur

cur +=1

left +=1# 收缩范围

ifleft > right:break

forrow in grid:

print(" ".join(map(str, row)))

C++

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

#include <iostream>

#include <vector>

using namespace std;

intmain() {

intn, m;

cin >> n >> m;

introws = m, cols = (n -1) / m +1;

// grid[i][j] == 0 则认为数字不够为 *

vector<vector<int>> grid(rows, vector<int>(cols,0));

// 上下左右,四侧的边界

inttop =0, bottom = rows -1, left =0, right = cols -1;

intcur =1;

while(cur <= n) {

// 从左到右

for(inti = left; i <= right && cur <= n; i++) {

grid[top][i] = cur++;

}

if(++top > bottom)break;// 收缩范围

// 从上到下

for(inti = top; i <= bottom && cur <= n; i++) {

grid[i][right] = cur++;

}

if(--right < left)break;// 收缩范围

// 从右到左

for(inti = right; i >= left && cur <= n; i--) {

grid[bottom][i] = cur++;

}

if(--bottom < top)break;// 收缩范围

// 从下到上

for(inti = bottom; i >= top && cur <= n; i--) {

grid[i][left] = cur++;

}

if(++left > right)break;// 收缩范围

}

// 输出结果

for(constauto &row : grid) {

for(size_t i =0; i < row.size(); ++i) {

if(row[i] ==0) {

cout <<"*";

}else{

cout << row[i];

}

if(i +1!= row.size()) cout <<" ";

elsecout << endl;

}

}

return0;

}



版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/29 15:51:12

购物省钱参考:爱创猫电商优惠券领取方式

外卖网购“隐形开支”太多&#xff1f;这份极致省钱手册&#xff0c;让你每月轻松多省几百块你有没有算过&#xff0c;自己每个月花在外卖和网购上的钱有多少&#xff1f;打开手机账单&#xff0c;那些十几二十块的外卖订单&#xff0c;几十上百的“凑单”商品&#xff0c;看似…

作者头像 李华
网站建设 2026/8/30 17:44:32

12、Red Hat Enterprise Linux硬件分析与管理指南

Red Hat Enterprise Linux硬件分析与管理指南 1. RPM包安装与信息查看 在安装示例包时,如果未安装 vpnc 包,会显示如下错误: error: Failed dependencies: vpnc is needed by startvpn-1.1-1.noarch若要强制安装该包以测试从示例中构建的软件包,可使用以下命令: r…

作者头像 李华
网站建设 2026/8/30 11:05:20

35、Linux 内核监控与调试:NUMA、AltSysRq 及 Kdump 全解析

Linux 内核监控与调试:NUMA、AltSysRq 及 Kdump 全解析 在 Linux 系统的运维和管理中,对内核的监控与调试至关重要。本文将深入探讨 NUMA 统计信息、AltSysRq 系统请求以及 Kdump 内核转储工具的使用,帮助你更好地理解和管理 Linux 内核。 1. NUMA 统计信息 NUMA(Non-Un…

作者头像 李华
网站建设 2026/8/29 22:13:21

DataEase开源BI工具完整指南:从零开始的数据可视化之旅

DataEase开源BI工具完整指南&#xff1a;从零开始的数据可视化之旅 【免费下载链接】DataEase 人人可用的开源 BI 工具 项目地址: https://gitcode.com/feizhiyun/dataease DataEase是一款人人可用的开源BI工具&#xff0c;让数据分析变得简单直观。作为一款基于GPLv3协…

作者头像 李华
网站建设 2026/8/30 3:34:41

Gutenberg性能优化终极指南:零成本加速WordPress编辑器

你是否曾经在编辑WordPress文章时&#xff0c;眼睁睁看着那个彩色的小圈圈转个不停&#xff1f;当页面加载缓慢、操作卡顿成为日常&#xff0c;是时候彻底解决Gutenberg编辑器的性能问题了。本文将从根源分析到实战验证&#xff0c;为你提供一套完整的优化方案。 【免费下载链接…

作者头像 李华
网站建设 2026/8/30 3:43:31

ag-ui与LangGraph集成终极指南:构建企业级AI工作流的完整教程

ag-ui与LangGraph集成终极指南&#xff1a;构建企业级AI工作流的完整教程 【免费下载链接】ag-ui 项目地址: https://gitcode.com/gh_mirrors/agu/ag-ui 在当今AI技术快速发展的时代&#xff0c;构建可靠、可扩展的复杂工作流已成为企业数字化转型的关键挑战。传统的线…

作者头像 李华