用方向数组按右、下、左、上的顺序行走,遇到边界或已填格就右转。
OJ: luogu
题目 ID: P5731
难度:入门
标签:模拟矩阵python
日期: 2026-07-15 18:54
题意
给出 n,输出一个 n * n 的蛇形方阵。从左上角填 1 开始,按顺时针方向填完整个矩阵。每个数字占 3 个字符宽度。
思路
用二维列表 matrix 保存方阵,未填的位置为 0。
蛇形填数的方向顺序固定为:
text
右 -> 下 -> 左 -> 上所以准备方向数组:
text
[(0, 1), (1, 0), (0, -1), (-1, 0)]每填完一个数,先尝试沿当前方向走到下一格。如果下一格越界,或者已经填过数,就把方向右转一格,再计算下一格。
最后输出矩阵时,每个数字用 f"{value:3d}" 保证宽度为 3。
这题是矩阵模拟和格式化输出练习,不创建 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:二维矩阵可以用列表推导式创建。/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:用"".join(...)拼接一整行输出。directions[direction]用下标选择当前方向。direction = (direction + 1) % 4表示按顺时针右转。f"{value:3d}"表示整数右对齐,占3个字符宽度。
代码
python
n = int(input())
matrix = [[0 for _ in range(n)] for _ in range(n)]
directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
row = 0
col = 0
direction = 0
for value in range(1, n * n + 1):
matrix[row][col] = value
dr, dc = directions[direction]
next_row = row + dr
next_col = col + dc
if not (0 <= next_row < n and 0 <= next_col < n) or matrix[next_row][next_col] != 0:
direction = (direction + 1) % 4
dr, dc = directions[direction]
next_row = row + dr
next_col = col + dc
row, col = next_row, next_col
for line in matrix:
print("".join(f"{value:3d}" for value in line))cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int a[15][15]; // 蛇形方阵
int n;
// 方向: 右、下、左、上
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};
int main() {
cin >> n;
int x = 1, y = 1, dir = 0;
for (int v = 1; v <= n * n; v++) {
a[x][y] = v;
// 尝试沿当前方向走下一步
int nx = x + dx[dir];
int ny = y + dy[dir];
// 如果越界或已填数,右转方向
if (nx < 1 || nx > n || ny < 1 || ny > n || a[nx][ny] != 0) {
dir = (dir + 1) % 4;
nx = x + dx[dir];
ny = y + dy[dir];
}
x = nx;
y = ny;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++)
printf("%3d", a[i][j]);
printf("\n");
}
return 0;
}Pythonic 写法
方向数组蛇形:
python
n=int(input())
g=[[0]*n for _ in range(n)]
dirs=[(0,1),(1,0),(0,-1),(-1,0)]
r=c=d=0
for v in range(1,n*n+1):
g[r][c]=v
nr,nc=r+dirs[d][0],c+dirs[d][1]
if not (0<=nr<n and 0<=nc<n) or g[nr][nc]:
d=(d+1)%4
nr,nc=r+dirs[d][0],c+dirs[d][1]
r,c=nr,nc
for row in g:
print(''.join(f'{x:3d}' for x in row))复杂度
每个格子填一次,时间复杂度是
总结
蛇形矩阵的关键是“尝试前进,不能走就右转”。用方向数组可以避免写四段重复逻辑。