C#编写3x3x3蛇形立方求解程序时如何定义蛇身结构
3x3x3蛇形立方蛇身构造逻辑实现方案
第一步:统一连接标记定义
你当前用数组存储每个块的连接标记的思路可行,先明确定义消除歧义:数组索引为i的元素值,代表当前块第i个小立方和第i+1个小立方的连接规则:1= 直线连接,和前一段延伸方向保持一致0= 侧边连接,和前一段延伸方向成90度垂直转向
每个块的数组长度比块包含的小立方数少1即可(你当前的代码里部分块的数组长度和小立方数相等,比如长度3的块只需要2个标记位,可调整优化)第二步:核心生成逻辑说明
用三维坐标记录每个小立方的位置,3x3x3立方的坐标(x,y,z)取值范围均为0~2,核心生成逻辑如下:
- 初始化起点坐标、初始延伸方向、已占用坐标集合
- 按顺序遍历你定义的17个蛇块:
3. 每个块的第一个小立方坐标继承上一个块最后一个小立方的坐标,延伸方向继承上一个块最后一段的方向
4. 遍历当前块的连接标记数组:- 标记为
1时,下一个小立方坐标沿当前方向偏移1个单位 - 标记为
0时,从剩余5个三维方向中排除与当前方向相同、相反的方向,逐个校验坐标未被占用、且在边界内,选择合法方向作为新的延伸方向,再计算下一个坐标
- 标记为
- 每生成一个新坐标就加入已占用集合,避免重复
- 第三步:可直接复用的示例代码
// 定义三维方向:上下左右前后共6个方向 int[][] directions = new int[][] { new int[] {1,0,0}, new int[] {-1,0,0}, new int[] {0,1,0}, new int[] {0,-1,0}, new int[] {0,0,1}, new int[] {0,0,-1} }; List<(int x, int y, int z)> allCubes = new List<(int x, int y, int z)>(); HashSet<(int x, int y, int z)> used = new HashSet<(int x, int y, int z)>(); // 初始化起点和初始方向 var currentPos = (x:0, y:0, z:0); int currentDirIndex = 0; // 初始沿x轴正方向 allCubes.Add(currentPos); used.Add(currentPos); // 你定义的蛇块列表初始化 snakeParts.Add(snakePart1); snakeParts.Add(snakePart2); // 剩下的15个块依次Add进去... foreach (var part in snakeParts) { foreach (var link in part) { if (link == 1) { // 直线延伸 var dir = directions[currentDirIndex]; var newPos = (x: currentPos.x + dir[0], y: currentPos.y + dir[1], z: currentPos.z + dir[2]); // 校验合法性 if (IsValid(newPos, used)) { allCubes.Add(newPos); used.Add(newPos); currentPos = newPos; } } else { // 转向,找合法的新方向 for (int i = 0; i < directions.Length; i++) { // 排除和当前方向相同/相反的方向(要90度转向) if (i == currentDirIndex || i == currentDirIndex ^ 1) continue; var dir = directions[i]; var newPos = (x: currentPos.x + dir[0], y: currentPos.y + dir[1], z: currentPos.z + dir[2]); if (IsValid(newPos, used)) { currentDirIndex = i; allCubes.Add(newPos); used.Add(newPos); currentPos = newPos; break; } } } } } // 合法性校验方法 bool IsValid((int x, int y, int z) pos, HashSet<(int x, int y, int z)> used) { return pos.x >=0 && pos.x <3 && pos.y >=0 && pos.y <3 && pos.z >=0 && pos.z <3 && !used.Contains(pos); }
如果需要穷举所有可行解法,只需要在转向时无合法方向的场景下增加回溯逻辑,回退到上一个可选分支重新选择方向即可。
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

