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

迷宫两点间最小转弯路径求解:Dijkstra实现结果非最优问题排查

问题描述

给定由0和1组成的2D矩阵,仅可在值为1的位置移动,从起点(x,y)出发,可向上下左右4个相邻方向移动,对应坐标为(x+1, y)、(x-1, y)、(x, y+1)、(x, y-1)。要求找到从起点(x,y)到终点(s,t)的转弯次数最少的路径。

代码问题分析

你当前的实现存在状态维度缺失的问题:turns数组仅记录了到达每个坐标的最小转弯次数,没有记录到达该坐标时的移动方向。同个坐标可以通过不同方向抵达,即便两次抵达的转弯次数相同,不同的入方向也会对后续移动的转弯成本产生影响,仅按坐标去重会丢失可能得到更优解的合法状态,最终导致部分用例无法得到最优解。

举个简单例子:到达坐标(2,2)时存在两个有效状态:

  • 状态1:从上方移动到(2,2),方向向下,转弯次数2
  • 状态2:从左侧移动到(2,2),方向向右,转弯次数2
    你当前的逻辑会把后到的状态2直接过滤掉,但如果后续终点在(2,5),状态2只需要再直走3步不用额外转弯,状态1则需要先转一次弯再走,此时就会丢失最优解。
修正方案

将状态维度扩展为三维turns[x][y][d],d为0~3对应四个移动方向,额外处理起点无初始方向的特殊情况,保证所有合法状态都能被正确判断。

修正后的核心代码参考:

pair<int,int> go[4] = {{-1,0}, {0,1}, {1,0}, {0,-1}};
const int INF = 0x3f3f3f3f;
int turns[105][105][4]; // 按实际矩阵大小调整维度,turns[x][y][d]表示到达(x,y)且方向为d的最小转弯次数

bool minimize(int &x, const int &y){
    if(x > y){
        x = y;
        return true;
    }
    return false;
}

struct Node{
    pair<int,int> point;
    int turn, direc;

    Node(pii _point, int _turn, int _direc){
        point = _point;
        turn = _turn;
        direc = _direc;
    }

    bool operator < (const Node &x) const{
        return turn > x.turn;
    }
};

void dijkstra(){
    memset(turns, 0x3f, sizeof turns);
    priority_queue<Node> pq;
    // 起点初始化,四个方向都可以走,首次移动转弯次数为0
    for(int i=0;i<4;i++){
        int nx = xHome + go[i].first;
        int ny = yHome + go[i].second;
        if(nx>=1 && nx<=row && ny>=1 && ny<=col && matrix[nx][ny]){
            turns[nx][ny][i] = 0;
            pq.push(Node({nx, ny}, 0, i));
        }
    }

    while(!pq.empty()){
        Node cur = pq.top();
        pq.pop();
        pii point = cur.point;
        int direc = cur.direc;
        int cur_turn = cur.turn;
        
        if(cur_turn > turns[point.first][point.second][direc]) continue;

        for(int i = 0; i < 4; i++){
            int x = point.first + go[i].first;
            int y = point.second + go[i].second;
            if(x<1 || x > row || y<1 || y > col) continue;
            if(matrix[x][y]){
                int new_turn = cur_turn + (i != direc);
                if(minimize(turns[x][y][i], new_turn))
                    pq.push(Node({x, y}, new_turn, i));
            }
        }
    }
    // 最终答案是turns[s][t][0~3]四个值中的最小值
}
补充说明
  • 如果你要保留起点转弯次数初始为-1的写法也可以,只要给状态加上方向维度即可解决核心问题
  • 得到所有方向到达终点的转弯次数后,取最小值即为所求的最少转弯次数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:45:04