【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
相关推荐
workflower几秒前
Agentic AI 时代的企业ICT 基础设施运维
运维·人工智能·机器学习·重构·云计算·汽车
wuminyu1 小时前
JMM学习总结:深入理解happens-before关系
java·linux·c语言·jvm·c++
xxwl5851 小时前
区域赛分类题解
c++·笔记·学习·算法
青少儿编程课堂2 小时前
蓝桥杯+全国青少年信息素养大赛+电子学会PythonC/C++考级:最长公共子序列LCS解析
c++·python·算法·bfs·信息学竞赛
代钦塔拉3 小时前
【C++/Qt 进阶】设计模式系列(2):工厂模式——从游戏角色到披萨店
c++·算法·设计模式
sxgzzn4 小时前
电力设备故障定位与特种电缆局放监控技术分析
重构·无人机·gis局放在线监测·矿用高压电缆绝缘故障检测装置·光伏运维管理系统
把我格子衫拿来5 小时前
VTK 与 Qt 的 CMake 工程怎么组织?模块、工具链与二进制兼容排错
c++·qt·vtk·cmake·工程实践
灯澜忆梦5 小时前
【面向对象编程c++】| 指针与自定义数据类型
开发语言·c++·算法
xxwl5856 小时前
区域赛算法模版第八章---贪心(Greedy)
c++·笔记·学习·算法
雾沉川6 小时前
Visual C++运行库合集 v105.0 安装教程
开发语言·c++·dll