题目
思路和解题方法
问题理解:此题要求找出将一条由16节正方形构成的玩具蛇放入4x4的方格中的不同方式数。每节蛇可以是直线或直角转弯,且蛇的形状需要完全覆盖盒子里的16个格子,每个格子仅被蛇的一个部分占据。
状态表示:使用一个二维数组
st[4][4]
来标记每个格子是否被蛇占用(0表示未占用,1表示占用)。同时,使用深度优先搜索(DFS)来探索所有可能的放置方式。DFS策略:
- 参数定义:
dfs(x, y, len)
函数中,x
和y
表示当前蛇头的位置坐标,len
表示当前已经放置蛇的节段数目。- 递归终止条件:当
len
达到16时,说明蛇的所有部分都已放置完毕,方案数加1。- 边界判断与重复检查:每次尝试移动前,先检查新位置是否在边界内以及是否已访问过。
- 移动方向:对于当前位置,尝试向上、下、左、右四个方向移动,每次移动后递归调用自身,探索新的路径。
- 回溯:在每个方向探索结束后,需要恢复现场,即撤销当前位置的占用标记,以允许探索其他路径。
代码实现:
- 首先遍历所有可能的起始位置,对每个起始位置调用
dfs
函数。- 在
dfs
函数中,进行上述逻辑处理,包括移动、计数、回溯等操作。
c++ 代码
#include <iostream>
using namespace std;
// 方向数组,dx表示行变化,dy表示列变化,分别对应上、下、左、右四个方向
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};
// st数组用来标记网格中的每个格子是否已经被蛇占用过
int st[4][4];
// res用于记录可以成功放置玩具蛇的总方案数
int res = 0;
// 深度优先搜索函数,探索放置蛇的路径
void dfs(int x, int y, int len) {
// 如果当前位置超出网格范围,则返回
if (x < 0 || y < 0 || x >= 4 || y >= 4) {
return;
}
// 如果当前位置已经走过,则返回,避免重复路径
if (st[x][y] == 1) {
return;
}
// 如果蛇的长度已经达到15(即全部摆放完毕),方案数加一并返回
if (len == 15) {
res++;
return;
}
// 标记当前位置已被占用
st[x][y] = 1;
// 依次尝试向上、下、左、右四个方向进行下一步探索
for (int i = 0; i < 4; i++) {
dfs(x + dx[i], y + dy[i], len + 1);
}
// 回溯:恢复当前位置为未访问状态,以便进行其他路径的探索
st[x][y] = 0;
}
// 主函数
int main() {
// 遍历网格的每一个起点,启动深度优先搜索寻找所有可能的蛇形路径
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
dfs(i, j, 0);
}
}
// 输出所有可行的蛇形路径总数
cout << res << endl;
return 0;
}
Java 版本(仅供参考)
import java.util.Arrays;
public class Main {
static int[][] st = new int[4][4];
static int res = 0;
static int[][] dx_dy = {{-1, 0, 1, 0}, {0, -1, 0, 1}};
public static void dfs(int x, int y, int len) {
if (x < 0 || y < 0 || x >= 4 || y >= 4) {
return;
}
if (st[x][y] == 1) {
return;
}
if (len == 15) {
res++;
return;
}
st[x][y] = 1;
for (int i = 0; i < 4; i++) {
dfs(x + dx_dy[0][i], y + dx_dy[1][i], len + 1);
}
st[x][y] = 0;
}
public static void main(String[] args) {
Arrays.stream(st).forEach(row -> Arrays.fill(row, 0)); // 初始化st数组
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
dfs(i, j, 0);
}
}
System.out.println(res);
}
}
Python 版本(仅供参考)
def dfs(x, y, len):
if x < 0 or y < 0 or x >= 4 or y >= 4:
return
if st[x][y] == 1:
return
if len == 15:
global res
res += 1
return
st[x][y] = 1
for i in range(4):
dfs(x + dx[i], y + dy[i], len + 1)
st[x][y] = 0
dx, dy = [-1, 0, 1, 0], [0, -1, 0, 1]
st = [[0]*4 for _ in range(4)]
res = 0
for i in range(4):
for j in range(4):
dfs(i, j, 0)
print(res)
代码细节:
- 递归函数:
dfs(x, y, len)
负责实际的搜索过程,其中(x, y)
是当前探索的位置,len
表示已经探索了多少个格子(即蛇的长度)。 - 边界检查:在尝试移动到新位置之前,先检查新位置是否还在网格范围内,防止越界。
- 重复检查:通过
st
数组避免重复访问同一格子,提高搜索效率,减少无效分支。 - 递归终止条件:当蛇的长度达到16时,说明找到了一个完整的解决方案,累加结果计数器
res
。 - 回溯:在递归返回前,撤销当前位置的占用标记,以便于从当前节点出发探索其他路径。
- 全面搜索:通过外层循环遍历所有可能的起始点,确保从每个格子出发都尝试寻找解。
觉得有用的话可以点点赞,支持一下。
如果愿意的话关注一下。会对你有更多的帮助。
每天都会不定时更新哦 >人< 。