#P3026. 螺旋数字矩阵(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 150
            Accepted: 52
            Difficulty: 4
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>模拟          
 
螺旋数字矩阵(100分)
思路:模拟
首先,我们定义了两个列表 dx 和 dy,它们分别表示在二维平面上向右、下、左、上移动时,x 和 y 坐标的变化量。
然后,我们定义了一个变量 d 来表示当前的移动方向,初始值为0,表示向右。
在一个循环中,我们不断地将数字填入矩阵,并将数字加一。然后,我们检查下一步的位置是否越界或者已经被填充过。如果是,我们就改变移动方向(通过将 d 加一并对4取余实现)。然后,我们根据新的方向更新 x 和 y 的值。仔细思考,这样可以完成顺时针的填充。
最后,我们打印出填充好的矩阵。每一行的数字之间用空格分隔,然后将数字转换为字符串,按行输出。
JavaScript
const readline = require('readline');
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
rl.on('line', (line) => {
    const [k, n] = line.split(' ').map(Number);
    const m = Math.floor((k - 1) / n) + 1;
    // 创建n * m的矩阵并初始化为'*'
    const g = Array.from({ length: n }, () => Array(m).fill('*'));
    // 从左上角开始填充
    let x = 0, y = 0;
    let num = 1; // 从1开始填充
    const dx = [0, 1, 0, -1]; // 方向数组
    const dy = [1, 0, -1, 0];
    let dirc = 0; // 方向
    while (num <= k) {
        g[x][y] = String(num);
        num++;
        // 判断下一步是否越界或已经被填充
        if (x + dx[dirc] < 0 || x + dx[dirc] >= n || y + dy[dirc] < 0 || y + dy[dirc] >= m || g[x + dx[dirc]][y + dy[dirc]] !== '*') {
            dirc = (dirc + 1) % 4; // 改变方向
        }
        x += dx[dirc];
        y += dy[dirc];
    }
    // 输出矩阵
    for (let i = 0; i < n; i++) {
        console.log(g[i].join(' '));
    }
    rl.close();
});
Java
import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        // 输入k和n
        int k = scanner.nextInt();
        int n = scanner.nextInt();
        int m = (k - 1) / n + 1;
        // 创建n * m的矩阵并初始化为'*'
        String[][] g = new String[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                g[i][j] = "*";
            }
        }
        // 从左上角开始填充
        int x = 0, y = 0;
        int num = 1; // 从1开始填充
        int[] dx = {0, 1, 0, -1}; // 方向数组
        int[] dy = {1, 0, -1, 0};
        int dirc = 0; // 方向
        while (num <= k) {
            g[x][y] = Integer.toString(num);
            num++;
            // 判断下一步是否越界或已经被填充
            if (x + dx[dirc] < 0 || x + dx[dirc] >= n || y + dy[dirc] < 0 || y + dy[dirc] >= m || !g[x + dx[dirc]][y + dy[dirc]].equals("*")) {
                dirc = (dirc + 1) % 4; // 改变方向
            }
            x += dx[dirc];
            y += dy[dirc];
        }
        // 输出矩阵
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                System.out.print(g[i][j] + " ");
            }
            System.out.println();
        }
    }
}
Python
k , n = map(int, input().split())
m = (k - 1) // n + 1
# n * m 的矩阵
g = [['*' for i in range(m)] for j in range(n)]
# 从左上角开始填充
x = 0
y = 0
# 从1开始填充
num = 1
# 螺旋顺时针填写
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
# 方向
dirc = 0
while num <= k:
    g[x][y] = num
    num += 1
    # 判断下一步是否越界
    if x + dx[dirc] < 0 or x + dx[dirc] >= n or y + dy[dirc] < 0 or y + dy[dirc] >= m or g[x + dx[dirc]][y + dy[dirc]] != '*':
        dirc = (dirc + 1) % 4
    x += dx[dirc]
    y += dy[dirc]
for i in range(n):
    print(' '.join(map(str, g[i])))
C++
#include <iostream>
#include <vector>
using namespace std;
int main() {
    int k, n;
    cin >> k >> n;
    int m = (k - 1) / n + 1;
    vector<vector<string>> g(n, vector<string>(m, "*"));
    int x = 0, y = 0;
    int num = 1;
    vector<int> dx = {0, 1, 0, -1};
    vector<int> dy = {1, 0, -1, 0};
    int dirc = 0;
    while (num <= k) {
        g[x][y] = to_string(num);
        num++;
        if (x + dx[dirc] < 0 || x + dx[dirc] >= n || y + dy[dirc] < 0 || y + dy[dirc] >= m || g[x + dx[dirc]][y + dy[dirc]] != "*") {
            dirc = (dirc + 1) % 4;
        }
        x += dx[dirc];
        y += dy[dirc];
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cout << g[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}
        题目描述
疫情期间,小红隔离在家,百无聊赖,在纸上写数字玩。他发明了一种写法:
给出数字个数n和行数m (1≤n,m≤999),从左上角的1开始,按照顺时针螺旋向内写方式,依次写出1,2,3..n,最终形成个一m行矩阵。 小红对这个矩阵有些要求
1.每行数字的个数一样多
2.列的数量尽可能少
3.填充数字时优先填充外部
4.数字不够时,使用单个*号占位
输入描述
输入一行,两个整数,空格隔开,依次表示n、m
输出描述
符合要求的唯一矩阵
样例1
输入
9 4
输出
1 2 3
* * 4
9 * 5
8 7 6
说明
9个数字写成4行,最少需要3列
样例2
输入
3 5
输出
1
2
3
*
*