问题描述
小U面临一个有趣的任务:在一个 n×n 的方阵中填入 1 到 n×n 这些数字,并要求按照蛇形顺序从右上角开始,沿着方阵的边界顺时针进行填充。蛇形填充的特殊排列方式使得每一层数字呈现出波浪形的排列方式。
例如,当 n=4 时,方阵应如下所示:
10 11 12 1
9 16 13 2
8 15 14 3
7 6 5 4
你需要编写程序输出填充后的方阵,确保格式的整齐性。
测试样例
样例1:
输入:
n = 4
输出:[[10, 11, 12, 1], [9, 16, 13, 2], [8, 15, 14, 3], [7, 6, 5, 4]]
样例2:
输入:
n = 5
输出:[[13, 14, 15, 16, 1], [12, 23, 24, 17, 2], [11, 22, 25, 18, 3], [10, 21, 20, 19, 4], [9, 8, 7, 6, 5]]
样例3:
输入:
n = 3
输出:[[7, 8, 1], [6, 9, 2], [5, 4, 3]]
题目分析
求解思路
1. 理解蛇形填充
蛇形填充意味着我们需要按照特定的顺序填充矩阵。具体来说,我们需要从右上角开始,沿着矩阵的边界顺时针填充数字,并且在每一层中数字的排列方式是波浪形的。
2. 数据结构选择
我们可以使用一个二维数组(矩阵)来存储填充的数字。二维数组非常适合表示矩阵,并且可以通过索引直接访问和修改矩阵中的元素。
3. 算法步骤
- 初始化矩阵:创建一个 n×n 的二维数组,并将其所有元素初始化为0。
- 定义方向:定义四个方向(右、下、左、上),并使用一个方向数组来控制移动。
- 填充数字:从右上角开始,按照定义的方向依次填充数字。每次填充一个数字后,检查下一个位置是否越界或已经填充过,如果是,则改变方向。
- 边界检查:在每次移动时,检查下一个位置是否越界或已经填充过。如果是,则改变方向。
算法采用
1. 模拟算法
我们可以通过模拟填充过程来解决这个问题。具体来说,我们可以使用一个循环来依次填充数字,并在每次填充后检查下一个位置是否需要改变方向。
2. 方向控制
我们可以使用一个方向数组来控制移动方向。每次遇到边界或已经填充的格子时,改变方向。
解题重点
1. 方向控制
方向控制是解决这类问题的关键。我们可以使用一个方向数组来定义移动方向,并通过改变方向来实现蛇形填充。
2. 边界检查
在每次移动时,我们需要检查下一个位置是否越界或已经填充过。如果是,则需要改变方向。
代码部分
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<vector<int>> solution(int n) {
// 初始化矩阵
vector<vector<int>> matrix(n, vector<int>(n, 0));
// 定义方向:右、下、左、上
vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
// 初始位置和方向
int x = 0, y = n - 1, dir = 0;
// 填充数字
for (int num = 1; num <= n * n; ++num) {
matrix[x][y] = num;
// 计算下一个位置
int nextX = x + directions[dir].first;
int nextY = y + directions[dir].second;
// 检查是否需要改变方向
if (nextX < 0 || nextX >= n || nextY < 0 || nextY >= n || matrix[nextX][nextY] != 0) {
dir = (dir + 1) % 4; // 改变方向
nextX = x + directions[dir].first;
nextY = y + directions[dir].second;
}
// 更新当前位置
x = nextX;
y = nextY;
}
return matrix;
}
int main() {
vector<vector<int>> a1 = solution(4);
cout << (a1 == vector<vector<int>>{{10, 11, 12, 1}, {9, 16, 13, 2}, {8, 15, 14, 3}, {7, 6, 5, 4}}) << endl;
vector<vector<int>> a2 = solution(5);
cout << (a2 == vector<vector<int>>{{13, 14, 15, 16, 1}, {12, 23, 24, 17, 2}, {11, 22, 25, 18, 3}, {10, 21, 20, 19, 4}, {9, 8, 7, 6, 5}}) << endl;
vector<vector<int>> a3 = solution(3);
cout << (a3 == vector<vector<int>>{{7, 8, 1}, {6, 9, 2}, {5, 4, 3}}) << endl;
return 0;
}