【C++ 代码分析与重构】常见 DFS 逻辑错误解析与修正

【C++ 代码分析与重构】常见 DFS 逻辑错误解析与修正

1. 原代码问题分析

给出的 DFS 代码存在多处编译错误 与逻辑缺陷,总结如下:

  1. 语法与编译错误:

    • 数组定义越界 :dx 和 dy 数组定义为了 int dx[4][4],应改为一维数组 int dx[4]。
    • 变量未定义 :在 dfs 函数中使用了未声明的变量 n、nx、ny。
    • 函数返回值丢失 :声明为 long long dfs() 但部分分支没有返回值。
  2. 逻辑与算法错误:

    • 方向遍历缺失 :代码没有使用 for 循环遍历上下左右四个方向。
    • 状态回溯与累加错误 :res 设为了全局变量并在多处混用,导致递归搜索路径上的点权累积错乱。
    • 坐标基准不一致 :主函数读入矩阵时使用的是 0-based 索引(0 到 n-1),但在调用 dfs 时传入了 dfs(1, 1),且终点判断为 x == n && y == n,导致起点终点坐标对不上。
    • 访问标记逻辑颠倒 :if 校验条件中写了 visited[nx][ny](已访问过才进入),应为 !visited[nx][ny](未访问才进入)。

2. 正确代码实现(记忆化搜索 / 深度优先搜索)

假设题目需求为:从左上角出发,在矩阵中按规则寻找一条路径,使沿途经过的点权之和最大。

以下是修复并优化后的完整代码:

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

const int MAXN = 1005;
int grid[MAXN][MAXN];
bool visited[MAXN][MAXN];
int n, m;

// 方向数组:上、右、下、左
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};

// dfs 返回从 (x, y) 出发能获得的最大点权和
long long dfs(int x, int y) {
    // 到达终点 (n-1, m-1)
    if (x == n - 1 && y == m - 1) {
        return grid[x][y];
    }

    long long max_sub_res = 0;
    visited[x][y] = true;

    // 遍历 4 个方向
    for (int i = 0; i < 4; i++) {
        int nx = x + dx[i];
        int ny = y + dy[i];

        // 边界检查、未访问检查、合法格子检查
        if (nx >= 0 && nx < n && ny >= 0 && ny < m && !visited[nx][ny] && grid[nx][ny] != 0) {
            max_sub_res = max(max_sub_res, dfs(nx, ny));
        }
    }

    visited[x][y] = false; // 回溯恢复现场

    return grid[x][y] + max_sub_res;
}

int main() {
    // 提高读写效率
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    if (!(cin >> n >> m)) return 0;

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }

    // 从起点 (0, 0) 开始搜索
    long long ans = dfs(0, 0);

    cout << ans << "\n";

    return 0;
}

3. 关键修正对比表

修改项 原代码问题 修正方法
方向数组 int dx[4][4] 改为 int dx[4] = {-1, 0, 1, 0}
坐标基准 输入用 0 到 n-1,搜索用 1 到 n 统一使用 0-based 坐标,起点 (0, 0),终点 (n-1, m-1)
访问条件 visited[nx][ny] 改为 !visited[nx][ny]
路径递归 缺少对四个方向的 for 循环遍历 添加 for (int i = 0; i < 4; i++)
返回值处理 直接修改全局 res 导致逻辑混淆 采用自底向上的递归返回值 grid[x][y] + max_sub_res
相关推荐
倒头就睡的小比特5 天前
算法竞赛C++常用的STL
c++·算法
weilx12345 天前
C++笔记-文件IO-<fcntl.h>
c++
Smileyqp沛沛5 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车5 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光5 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
吞下星星的少年·-·5 天前
C++ 萌新语法入门篇
c++·算法比赛
霍霍的袁5 天前
【C++】map 和 set 的使用 | 从用法到底层
开发语言·c++·学习·visual studio
another heaven5 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
程序猿编码5 天前
告别改源码适配模型:纯 C++ 可配置 LLM 推理引擎,全格式全结构兼容
c++·大模型·llm·推理引擎
此生决int5 天前
深入理解C++系列(20)——C++11(下)
开发语言·c++