在算法竞赛和日常编程练习中,蛇形方阵、螺旋矩阵、回形取数等 “矩阵路径填充” 类题目屡见不鲜。很多同学会陷入 “一题一解” 的误区,针对不同题目写不同逻辑,却忽略了这类问题的核心本质:按固定规则控制方向,在矩阵中完成有序遍历。
今天,我们就提炼出解决这类问题的通性通法 —— 方向向量法,用一套核心逻辑,搞定所有矩阵路径填充类题目。蛇形方阵作为最经典的入门案例,将成为我们掌握这套方法的最佳载体。
一、核心原理:方向向量法的 “三板斧”
所有矩阵路径填充问题,都可以拆解为 “定义方向→预判下一步→边界 / 规则转向” 三个核心步骤,这就是方向向量法的 “三板斧”,适用于任意维度、任意遍历规则的矩阵路径问题。
矩阵中的移动方向,本质是横纵坐标的增量变化。无论题目要求顺时针、逆时针、“之” 字形,还是自定义路径,都可以用两个一维数组(方向向量)统一表示。
对于二维矩阵的四方向移动(最常见场景),我们将方向抽象为 “右、下、左、上”,对应的坐标增量如下:
- 向右:横坐标 x 不变,纵坐标 y+1 →
dx[0] = 0, dy[0] = 1 - 向下:横坐标 x+1,纵坐标 y 不变 →
dx[1] = 1, dy[1] = 0 - 向左:横坐标 x 不变,纵坐标 y-1 →
dx[2] = 0, dy[2] = -1 - 向上:横坐标 x-1,纵坐标 y 不变 →
dx[3] = -1, dy[3] = 0
通法总结:无论题目要求多少个方向(如八方向、自定义方向),只需按规则列出坐标增量,存入dx、dy数组即可。
2. 第二板斧:预判先行,规避无效移动
矩阵遍历的关键是 **“先判断,再移动” ,而非 “先移动,再回退”。每一步填充前,先根据当前方向计算下一步的坐标 **,再判断该坐标是否符合规则。
通法总结:预判的核心是 “提前计算下一个位置”,避免出现越界、重复访问等无效移动,这是所有路径填充问题的通用逻辑。
3. 第三板斧:规则驱动,动态切换方向
当预判的下一步不合法(越界、已访问、违反题目规则)时,需要按题目要求切换方向。切换逻辑通过方向索引取模实现,保证方向循环切换。
通法总结:方向切换的本质是 “索引递增 + 取模”,pos = (pos + 1) % 方向总数,适用于所有循环方向的题目。
二、实战落地:用通法解决蛇形方阵问题
以经典的顺时针蛇形方阵为例,完整演示方向向量法的通性通法落地过程,代码可直接迁移至同类题目。
问题描述
给定正整数n,生成n×n矩阵,从(1,1)开始,顺时针螺旋填充1~n²的数字。
通法步骤拆解(完全遵循 “三板斧”)
步骤 1:定义核心变量(适配所有矩阵题)
- 矩阵数组
arr[N][N]:存储填充结果,需初始化为 0(标记 “未访问”)。 - 方向向量
dx[4]、dy[4]:表示四方向增量。 - 遍历变量:
x, y(当前坐标)、cnt(填充数值)、pos(当前方向索引)。
步骤 2:执行填充循环(核心通法逻辑)
循环条件:填充数值cnt ≤ n²(遍历完成)。循环内执行 “填充→预判→转向→移动” 四步,完全复用通法逻辑。
步骤 3:格式化输出
按行遍历矩阵,格式化打印,保证输出美观。
#include<bits/stdc++.h>
using namespace std;
const int N=15;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int arr[N][N];
int main(){
int n;
cin>>n;
int x=1,y=1;
int cnt=1;
int pos=0;
while(cnt<=n*n)
{
arr[x][y]=cnt;
int a=x+dx[pos],b=y+dy[pos];
if(a<1||a>n||b<1||b>n||arr[a][b]!=0){
pos=(pos+1)%4;
a=x+dx[pos];
b=y+dy[pos];
}
x=a;y=b;
cnt++;
}
for (int i = 1; i <=n; i++)
{
for (int j = 1; j <=n; j++)
{
printf("%3d ",arr[i][j]);
}
cout<<endl;
}
return 0;
}
三、通法迁移:一招搞定所有变体问题
掌握方向向量法后,无需重写逻辑,只需修改方向向量或合法性判断规则,即可解决所有矩阵路径填充变体,真正实现 “一通百通”。
变体 1:逆时针蛇形方阵
仅需修改方向向量顺序,将 “右、下、左、上” 改为 “右、上、左、下”:
int dx[4] = {0, -1, 0, 1}; // 右、上、左、下 int dy[4] = {1, 0, -1, 0};
变体 2:回形取数(从外圈到内圈,按行读取)
仅需修改合法性判断规则,将 “未访问” 改为 “已访问”,填充逻辑改为 “读取数值”,核心遍历框架完全不变。
变体 3:“之” 字形矩阵填充
仅需修改方向切换规则,当到达矩阵右边界时,方向改为 “向下 + 向左”,到达左边界时改为 “向下 + 向右”,方向向量和核心循环仍复用通法。
四、通法避坑指南(通用)
- 坐标索引统一:要么全程使用
1-based(如本文),要么全程0-based,避免混合使用导致越界。 - 初始化必须到位:矩阵的 “访问标记”(如本文的 0)必须初始化,否则垃圾值会导致合法性判断失效。
- 最后一步保护:填充到最后一个数值时,无需更新坐标,避免转向后越界(通法:
if (cnt < 总数量) 才移动)。 - 方向与规则匹配:方向向量的顺序,必须和 “转向逻辑” 严格对应,否则会出现遍历路径错误。
总结
矩阵路径填充类题目,看似千变万化,实则万变不离其宗。方向向量法通过 “抽象方向→预判下一步→规则转向” 的通性逻辑,将所有此类问题转化为同一套模板。