#P3026. 螺旋数字矩阵(100分)
-
1000ms
Tried: 151
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
*
*