You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++基于BFS求解矩阵最长路径时控制台输入大矩阵挂起问题

矩阵最长合法路径求解程序控制台输入大矩阵挂起问题

功能需求

求解N×M规模矩阵中的最长合法路径,规则如下:

  • 仅可向右(记为J)或向下(记为L)移动
  • 每次移动后下一个格子与当前格子的数值差绝对值≤k
  • 最终输出三个结果:路径长度、起始格子坐标、起点到终点的移动序列

问题现象

采用广度优先搜索(BFS)实现功能,小矩阵输入下运行正常,输入200×200规模矩阵时:

  • 通过控制台输入数据:程序无响应挂起
  • 通过文件读取输入:程序正常运行

相关代码

#include <iostream>
#include <stdlib.h>
#include <queue>
#include <vector>
#include <fstream>
#include <chrono>

using namespace std;
using namespace std::chrono;

struct pr {
    int i;
    int j;
};

void read(int arr[][301], int &n, int &m, int &k) {
    // 冗余代码:定义了文件流但未使用
    ifstream be("be.txt");
    int i, j;
    cin >> n >> m >> k;
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            cin >> arr[i][j];
        }
    }
}

bool checkRight(int arr[][301], int i, int j, int k, int m) {
    if (j + 1 <= m && abs(arr[i][j + 1] - arr[i][j]) <= k)
        return 1;
    return 0;
}

bool checkDownwards(int arr[][301], int i, int j, int k, int n) {
    if (i + 1 <= n && abs(arr[i + 1][j] - arr[i][j]) <= k)
        return 1;
    return 0;
}


void bfs(int dist[][301], int arr[][301], bool visited[][301], int i, int j, int n, int m, int k, int &max, pr &po, vector<int> &resol) {
    int maxDist = 0;
    int l, p;
    pr prev[301][301];
    for (l = 1; l <= n; l++) {
        for (p = 1; p <= m; p++) {
            prev[l][p].i = 0;
            prev[l][p].j = 0;
        }
    }
    pr pos;
    pos.i = 0;
    pos.j = 0;
    vector<int> res;
    queue<pr> q;
    pr next;
    next.i = i;
    next.j = j;
    for (l = 1; l <= n; l++) {
        for (p = 1; p <= m; p++) {
            dist[l][p] = 0;
        }
    }
    dist[i][j] = 0;
    visited[i][j] = 1;
    q.push(next);
    while (!q.empty()) {
        pr front = q.front();
        visited[front.i][front.j] = 1;
        q.pop();
        if (checkRight(arr, front.i, front.j, k, m) == 1) {
            next.i = front.i;
            next.j = front.j + 1;
            q.push(next);
            dist[front.i][front.j + 1] = dist[front.i][front.j] + 1;
            maxDist = dist[front.i][front.j + 1];
            pos.i = next.i;
            pos.j = next.j;
            prev[next.i][next.j].i = front.i;
            prev[next.i][next.j].j = front.j;
        }
        if (checkDownwards(arr, front.i, front.j, k, n) == 1) {
            next.i = front.i + 1;
            next.j = front.j;
            q.push(next);
            dist[front.i + 1][front.j] = dist[front.i][front.j] + 1;
            maxDist = dist[front.i + 1][front.j];
            pos.i = next.i;
            pos.j = next.j;
            prev[next.i][next.j].i = front.i;
            prev[next.i][next.j].j = front.j;
        }
    }

    if (maxDist > max) {
        max = maxDist;
        po.i = i;
        po.j = j;
        resol.clear();
        next.i = pos.i;
        next.j = pos.j;
        while (next.i != i or next.j != j) {
            if (next.i == prev[next.i][next.j].i) {
                resol.push_back(1);
                next.j = prev[next.i][next.j].j;
            }
            if (next.j == prev[next.i][next.j].j) {
                resol.push_back(0);
                next.i = prev[next.i][next.j].i;
            }
        }
    }

}

void search(int arr[][301], int n, int m, int k) {
    int max = 0;
    int dist[301][301];
    bool visited[301][301] = {0};
    int i, j;
    vector<int> resol;
    pr po;
    po.i = 0;
    po.j = 0;
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            if (visited[i][j] == 0)
                bfs(dist, arr, visited, i, j, n, m, k, max, po, resol);
        }
    }
    cout << max << endl;
    cout << po.i << " " << po.j << endl;
    for (i = resol.size() - 1; i >= 0; i--) {
        if (resol[i] == 0)
            cout << "L";
        else
            cout << "J";
    }
}

int main() {
    auto start = high_resolution_clock::now();
    int n, m, k;
    int arr[301][301];
    read(arr, n, m, k);
    search(arr, n, m, k);
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<seconds>(stop - start);
    cout<<endl<<duration.count();
}

测试用例

小矩阵测试用例

输入

5 4 1
7 7 9 7
4 5 3 4
6 6 5 2
4 7 8 2
1 2 3 4

输出

4
2 1
JLLJ
0

200×200大矩阵测试用例

输出

  • 控制台输入:程序挂起无响应
  • 文件输入:
20
183 53
LLJJJJJLJLLJLLLLLJLL
3

问题原因与解决方案

核心原因

C++的cin默认开启了与C标准IO流的同步,且默认每次输入后都会刷新输出缓冲区,导致大批量数据输入时性能极差。控制台输入的读写速度本身远低于文件读取,叠加cin的性能损耗,就会出现程序看起来无响应挂起的现象。

修复方案

在read函数开头添加两行代码,关闭cin的同步和自动刷新:

ios::sync_with_stdio(false);
cin.tie(nullptr);

同时可以删除read函数中未使用的ifstream be("be.txt");冗余代码。
修复后控制台输入大矩阵的速度会提升至和文件读取相当的水平,不会再出现挂起问题。


内容的提问来源于stack exchange,提问作者Dani Suba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:45:02