机考E卷100分题 - 螺旋数字矩阵

题目描述

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

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

输入描述

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

输出描述

符合要求的唯一矩阵

用例1

输入:

9 4
1

输出:

1 2 3
* * 4
9 * 5
8 7 6
1234

说明:

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

用例2

输入:

3 5
输出:

1
2
3
*
*
12345

说明:

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

用例3

输入:

120 7
1

输出:

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

解题思路

本题不难,主要就是模拟。按照题目的要求填充矩阵就可以了。

C++

#include <iostream>
#include <vector>
#include <cmath>

int main() {
    int n, m;
    std::cin >> n >> m; // 读取要填充的数字个数n和矩阵的行数m

    int cols = std::ceil(static_cast<double>(n) / m); // 计算矩阵的列数
    std::vector<std::vector<int>> matrix(m, std::vector<int>(cols, 0)); // 创建一个整型矩阵,默认初始化为0

    int num = 1; // 用于填充的数字从1开始
    int 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++; // 左边界右移
    }

    for (int i = 0; i < m; i++) { // 遍历矩阵的每一行
        for (int j = 0; j < cols; j++) { // 遍历矩阵的每一列
            if (matrix[i][j] == 0) { // 如果当前位置是0,则输出'*'
                std::cout << '*';
            } else { // 否则输出当前位置的数字
                std::cout << matrix[i][j];
            }
            if (j < cols - 1) { // 在同一行的数字之间打印空格
                std::cout << " ";
            }
        }
        std::cout << std::endl; // 每打印完一行后换行
    }

    return 0;
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

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(); // 输入完毕后关闭scanner

        int cols = (int) Math.ceil(n / (double) m); // 计算矩阵的列数
        int[][] matrix = new int[m][cols]; // 创建一个整型矩阵,默认初始化为0

        int num = 1; // 用于填充的数字从1开始
        int 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++; // 左边界右移
        }

        for (int i = 0; i < m; i++) { // 遍历矩阵的每一行
            for (int j = 0; j < cols; j++) { // 遍历矩阵的每一列
                if (matrix[i][j] == 0) { // 如果当前位置是0,则输出'*'
                    System.out.print('*');
                } else { // 否则输出当前位置的数字
                    System.out.print(matrix[i][j]);
                }
                if (j < cols - 1) { // 在同一行的数字之间打印空格
                    System.out.print(" ");
                }
            }
            System.out.println(); // 每打印完一行后换行
        }
    }
}
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748

javaScript

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

readline.on('line', (input) => {
  const [n, m] = input.split(' ').map(Number); // 读取要填充的数字个数n和矩阵的行数m
  const cols = Math.ceil(n / m); // 计算矩阵的列数
  const matrix = Array.from({ length: m }, () => Array(cols).fill(0)); // 创建一个整型矩阵,默认初始化为0

  let num = 1; // 用于填充的数字从1开始
  let 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++; // 左边界右移
  }

  for (let i = 0; i < m; i++) { // 遍历矩阵的每一行
    let row = '';
    for (let j = 0; j < cols; j++) { // 遍历矩阵的每一列
      row += matrix[i][j] === 0 ? '*' : matrix[i][j]; // 如果当前位置是0,则输出'*',否则输出当前位置的数字
      if (j < cols - 1) row += ' '; // 在同一行的数字之间添加空格
    }
    console.log(row); // 打印每一行
  }

  readline.close();
});
123456789101112131415161718192021222324252627282930313233343536373839404142

Python

import math

n, m = map(int, input().split()) # 读取要填充的数字个数n和矩阵的行数m
cols = math.ceil(n / m) # 计算矩阵的列数
matrix = [[0 for _ in range(cols)] for _ in range(m)] # 创建一个整型矩阵,默认初始化为0

num = 1 # 用于填充的数字从1开始
top, bottom, left, right = 0, m - 1, 0, cols - 1
while num <= n:
    for i in range(left, right + 1): # 从左到右填充上边界
        if num <= n:
            matrix[top][i] = num
            num += 1
    top += 1 # 上边界下移
    for i in range(top, bottom + 1): # 从上到下填充右边界
        if num <= n:
            matrix[i][right] = num
            num += 1
    right -= 1 # 右边界左移
    for i in range(right, left - 1, -1): # 从右到左填充下边界
        if num <= n:
            matrix[bottom][i] = num
            num += 1
    bottom -= 1 # 下边界上移
    for i in range(bottom, top - 1, -1): # 从下到上填充左边界
        if num <= n:
            matrix[i][left] = num
            num += 1
    left += 1 # 左边界右移

for row in matrix: # 遍历矩阵的每一行
    print(' '.join('*' if val == 0 else str(val) for val in row)) # 如果当前位置是0,则输出'*',否则输出当前位置的数字
1234567891011121314151617181920212223242526272829303132

C语言

#include <stdio.h>
#include <math.h>

int main() {
    int n, m;
    scanf("%d %d", &n, &m); // 读取要填充的数字个数n和矩阵的行数m

    int cols = (int)ceil((double)n / m); // 计算矩阵的列数
    int matrix[m][cols]; // 创建一个整型矩阵,默认初始化为0
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < cols; j++) {
            matrix[i][j] = 0;
        }
    }

    int num = 1; // 用于填充的数字从1开始
    int 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++; // 左边界右移
    }

    for (int i = 0; i < m; i++) { // 遍历矩阵的每一行
        for (int j = 0; j < cols; j++) { // 遍历矩阵的每一列
            if (matrix[i][j] == 0) { // 如果当前位置是0,则输出'*'
                printf("* ");
            } else { // 否则输出当前位置的数字
                printf("%d ", matrix[i][j]);
            }
        }
        printf("\n"); // 每打印完一行后换行
    }

    return 0;
}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849

完整用例

用例1

4 2
1

用例2

10 2
1

用例3

3 3
1

用例4

11 5
1

用例5

7 4
1

用例6

5 1
1

用例7

12 4
1

用例8

2 2
1

用例9

20 6
1

用例10

8 3
1
#牛客创作赏金赛#

主要记录自己的刷题日常,学而时习之。

全部评论

相关推荐

从输入URL到页面加载发生了什么:总体来说分为以下几个过程:&nbsp;1.DNS解析&nbsp;2.TCP连接&nbsp;3.发送HTTP请求&nbsp;4.服务器处理请求并返回HTTP报文&nbsp;5.浏览器解析渲染页面&nbsp;6.连接结束。简述了一下各个过程的输入输出作用:以下是对从输入&nbsp;URL&nbsp;到页面加载各过程的输入、输出或作用的一句话描述:DNS&nbsp;解析:&nbsp;输入:用户在浏览器地址栏输入的域名(如&nbsp;www.example.com)。输出:对应的&nbsp;IP&nbsp;地址(如&nbsp;192.168.1.1)。作用:将易于记忆的域名转换为计算机能够识别和用于网络通信的&nbsp;IP&nbsp;地址,以便浏览器与目标服务器建立连接。TCP&nbsp;连接:&nbsp;输入:浏览器获得的服务器...
明天不下雨了:参考一下我的说法: 关键要讲出输入网址后涉及的每一个网络协议的工作原理和作用: 涉及到的网络协议: HTTP/HTTPS协议->DNS协议->TCP协议->IP协议->ARP协议 面试参考回答: 第一次访问(本地没有缓存时): 一般我们在浏览器地址栏输入的是一个域名。 浏览器会先解析 URL、解析出域名、资源路径、端口等信息、然后构造 HTTP 请求报文。浏览器新开一个网络线程发起HTTP请求(应用层) 接着进行域名解析、将域名解析为 IP 地址 浏览器会先检查本地缓存(包括浏览器 DNS 缓存、操作系统缓存等)是否已解析过该域名 如果没有、则向本地 DNS 服务器请求解析; 本地服务器查不到会向更上层的 DNS 服务器(根域名服务器->顶级域名服务器->权威域名服务器询问)递归查询 最终返回该域名对应的 IP 地址。(应用层DNS协议)DNS 协议的作用: 将域名转换为 IP 地址。 由于 HTTP 是基于 TCP 传输的、所以在发送 HTTP 请求前、需要进行三次握手、在客户端发送第一次握手的时候、( 浏览器向服务器发送一个SYN(同步)报文、其中包含客户端的初始序列号。TCP头部设置SYN标志位、并指定客户端端口 同时填上目标端口和源端口的信息。源端口是浏览器随机生成的、目标端口要看是 HTTP 还是 HTTPS、如果是 HTTP 默认目标端口是 80、如果是 HTTPS 默认是 443。(传输层) 然后到网络层:涉及到(IP协议) 会将TCP报文封装成IP数据包、添加IP头部,包含源IP地址(浏览器)和目标IP地址(服务器)。IP 协议的作用: 提供无连接的、不可靠的数据包传输服务。 然后到数据链路层、会通过 ARP 协议、获取目标的路由器的 MAC 地址、然后会加上 MAC 头、填上目标 MAC 地址和源 MAC 地址。 然后到物理层之后、直接把数据包、转发给路由器、路由器再通过下一跳、最终找到目标服务器、然后目标服务器收到客户的 SYN 报文后,会响应第二次握手。 当双方都完成三次握手后、如果是 HTTP 协议、客户端就会将 HTTP 请求就会发送给目标服务器。如果是 HTTPS 协议、客户端还要和服务端进行 TLS 四次握手之后、客户端才会将 HTTP 报文发送给目标服务器。 目标服务器收到 HTTP 请求消息后、就返回 HTTP 响应消息、浏览器会对响应消息进行解析渲染、呈现给用户
点赞 评论 收藏
分享
04-29 15:00
东华大学 财务
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务