【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
相关推荐
曦樂~7 小时前
Cpp面筋
c语言·c++
道尔柯南8 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
十二11 小时前
【洛谷题解】P1083 [NOIP 2012 提高组] 借教室(二分答案 + 差分)
数据结构·c++·算法·蓝桥杯
D e re k ZH13 小时前
C++ 从零入门(一):基础语法与程序结构
数据结构·c++·算法
zjxtxdy15 小时前
C++面向对象程序开发-类与对象
开发语言·c++
東隅已逝,桑榆非晚16 小时前
算法6. 双指针法-查找总价格为目标的两个商品
c++·学习·算法
qq_4069810317 小时前
c++拷贝构造函数
开发语言·c++
H.莓飛19 小时前
【C++】【STL】vector_OJ题
linux·服务器·开发语言·数据结构·c++·visual studio
Rabitebla19 小时前
【Linux操作系统】进程篇(十一):进程程序替换——从底层原理到 exec 函数族
linux·服务器·c++·笔记·学习·算法
沫璃染墨19 小时前
从零入门计算机网络系列(十五):TCP可靠传输机制详解——从序号与确认应答到乱序处理
服务器·网络·c++·tcp/ip·tcp