C++ 2D数组遍历递归实现国际象棋寻路返回值异常问题排查
问题背景
要解决的国际象棋逻辑判断问题:给定棋盘尺寸、皇后坐标、国王起始坐标、目标坐标,判断国王能否在不进入皇后攻击覆盖格子的前提下走到目标格子。递归实现的代码返回值异常,需要排查错误。
原始问题代码
#include <bits/stdc++.h> using namespace std; #define ll long long int n; int qx, qy; int kx, ky; int cx, cy; vector<vector<int>> board; vector<vector<bool>> visited; vector<int> temp; bool done; void initboard(){ for(int i = 0; i < n; i ++){ for(int j = 0; j < n; j ++){ if(i == qy-1 || j == qx-1){ temp.push_back(3); } else if(abs(i+1-qy) == abs(j+1-qx)){ temp.push_back(3); } else if(i == ky-1 && j == kx-1){ temp.push_back(0); } else if(i == cy-1 && j == cx-1){ temp.push_back(1); } else{ temp.push_back(2); } } board.insert(board.begin(),temp); temp = {}; } } bool safe(int x, int y){ return board[y][x]==2; } bool solve(int x, int y){ if(!done){ visited[y][x] = 1; if(board[y][x] == 3){ return 0; } else if(y == cy-1 && x == cx-1){ done = 1; return 1; } vector<vector<int>> tovisit = {{x+1,y}, {x-1,y}, {x,y+1}, {x,y-1},{x+1,y+1}, {x+1,y-1}, {x-1,y+1}, {x-1,y-1}}; for(vector<int> next : tovisit){ if(done) return 1; if(!visited[next[1]][next[0]] && next[0]>-1 && next[0]<n && next[1]>-1 && next[1]<n){ solve(next[0],next[1]); } } } else{ return 1; } } int main(){ cin>>n>>qx>>qy>>kx>>ky>>cx>>cy; initboard(); for(int i = 0; i < n; i ++){ for(int j = 0; j < n; j++){ cout<<board[i][j]<<" "; } cout<<"\n"; } cout<<solve(kx-1,ky-1); return 0; }
错误排查
- visited数组未初始化:代码仅声明了visited全局变量,未分配对应尺寸的内存、也未初始化为false,访问时会出现越界或随机值,导致逻辑异常。
- 行插入逻辑错误:initboard函数中使用
board.insert(board.begin(),temp)插入每行,会将行顺序完全倒置,坐标映射完全错乱,应改为board.push_back(temp)。 - 边界检查顺序错误:遍历下一个坐标时,先访问
visited[next[1]][next[0]]再判断坐标合法性,坐标越界时会直接触发数组访问越界崩溃,需要先判断坐标是否在棋盘范围内,再判断是否访问过。 - 递归返回值处理缺失:递归调用
solve(next[0],next[1])时没有接收返回值,同时solve函数在遍历完所有方向未找到路径时,没有返回false,属于非void函数未明确返回值的未定义行为。 - 访问标记逻辑错误:进入格子后先标记为已访问,再判断是否是皇后攻击范围,即使当前格子是禁止进入的区域,也会被标记为已访问,后续无法再遍历。
核心修复点
- main函数中初始化visited:
visited.resize(n, vector<bool>(n, false));
- 调整initboard的行插入逻辑为push_back。
- 调整solve函数中坐标判断顺序,补全返回值逻辑:
bool solve(int x, int y){ if(done) return true; // 先判断当前格子是否合法 if(board[y][x] == 3) return false; if(y == cy-1 && x == cx-1){ done = true; return true; } visited[y][x] = true; vector<vector<int>> tovisit = {{x+1,y}, {x-1,y}, {x,y+1}, {x,y-1},{x+1,y+1}, {x+1,y-1}, {x-1,y+1}, {x-1,y-1}}; for(auto &next : tovisit){ int nx = next[0], ny = next[1]; if(nx >=0 && nx <n && ny >=0 && ny <n && !visited[ny][nx]){ if(solve(nx, ny)) return true; } } return false; }
内容的提问来源于stack exchange,提问作者NotCoding
相关产品推荐
相关产品推荐

