解题思路

这是一道迷宫寻路问题,主要思路如下:

  1. 问题分析:

    • n×m的格子迷宫
    • 起点(0,0),终点(0,m-1)
    • 每个格子是0(障碍)或1(可通过)
    • 上下左右四个方向移动
    • 不同方向消耗不同体力值
  2. 移动规则:

    • 向上:消耗3点体力
    • 向右/左:消耗1点体力
    • 向下:不消耗体力
    • 体力不足时无法移动
  3. 解决方案:

    • 使用BFS搜索最短路径
    • 记录每个状态的前驱节点
    • 使用体力值进行剪枝

代码

#include <bits/stdc++.h>
using namespace std;

// 方向数组
const int dirx[] = {-1, 0, 1, 0};  // 上右下左
const int diry[] = {0, 1, 0, -1};
const int value[] = {3, 1, 0, 1};  // 对应方向的体力消耗

// 节点结构
struct Node {
    int x, y;    // 坐标
    int p;       // 剩余体力
    int pre;     // 前驱节点索引
    
    Node(int x, int y, int p, int pre = -1) 
        : x(x), y(y), p(p), pre(pre) {}
    
    bool operator < (const Node &other) const {
        return p > other.p;
    }
};

int main() {
    int n, m, p;
    while(cin >> n >> m >> p) {
        // 读入迷宫地图
        vector<vector<int>> mp(n, vector<int>(m));
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                cin >> mp[i][j];
            }
        }
        
        // BFS搜索
        deque<Node> que;
        vector<vector<bool>> used(n, vector<bool>(m, false));
        que.push_back(Node(0, 0, p));
        used[0][0] = true;
        
        int head = 0;
        bool found = false;
        int ans = 0;
        
        while(!que.empty() && head < que.size()) {
            auto now = que[head++];
            
            // 到达终点
            if(now.x == 0 && now.y == m-1) {
                found = true;
                ans = head - 1;
                break;
            }
            
            // 尝试四个方向
            for(int i = 0; i < 4; i++) {
                int tx = now.x + dirx[i];
                int ty = now.y + diry[i];
                int tp = now.p - value[i];
                
                // 判断是否可以移动
                if(tx >= 0 && tx < n && ty >= 0 && ty < m && 
                   mp[tx][ty] == 1 && !used[tx][ty] && tp >= 0) {
                    que.push_back(Node(tx, ty, tp, head-1));
                    used[tx][ty] = true;
                }
            }
        }
        
        // 输出结果
        if(!found) {
            cout << "Can not escape!" << endl;
        } else {
            // 重建路径
            stack<int> st;
            while(que[ans].pre != -1) {
                st.push(que[ans].pre);
                ans = que[ans].pre;
            }
            
            // 输出路径
            while(!st.empty()) {
                cout << "[" << que[st.top()].x << "," 
                     << que[st.top()].y << "],";
                st.pop();
            }
            cout << "[0," << m-1 << "]" << endl;
        }
    }
    return 0;
}
import java.util.*;

public class Main {
    // 方向数组
    static int[] dirx = {-1, 0, 1, 0};  // 上右下左
    static int[] diry = {0, 1, 0, -1};
    static int[] value = {3, 1, 0, 1};  // 对应方向的体力消耗
    
    // 节点类
    static class Node {
        int x, y, p, pre;
        
        Node(int x, int y, int p, int pre) {
            this.x = x;
            this.y = y;
            this.p = p;
            this.pre = pre;
        }
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while(sc.hasNext()) {
            int n = sc.nextInt();
            int m = sc.nextInt();
            int p = sc.nextInt();
            
            // 读入迷宫地图
            int[][] mp = new int[n][m];
            for(int i = 0; i < n; i++) {
                for(int j = 0; j < m; j++) {
                    mp[i][j] = sc.nextInt();
                }
            }
            
            // BFS搜索
            List<Node> que = new ArrayList<>();
            boolean[][] used = new boolean[n][m];
            que.add(new Node(0, 0, p, -1));
            used[0][0] = true;
            
            int head = 0;
            boolean found = false;
            int ans = 0;
            
            while(head < que.size()) {
                Node now = que.get(head++);
                
                if(now.x == 0 && now.y == m-1) {
                    found = true;
                    ans = head - 1;
                    break;
                }
                
                for(int i = 0; i < 4; i++) {
                    int tx = now.x + dirx[i];
                    int ty = now.y + diry[i];
                    int tp = now.p - value[i];
                    
                    if(tx >= 0 && tx < n && ty >= 0 && ty < m && 
                       mp[tx][ty] == 1 && !used[tx][ty] && tp >= 0) {
                        que.add(new Node(tx, ty, tp, head-1));
                        used[tx][ty] = true;
                    }
                }
            }
            
            if(!found) {
                System.out.println("Can not escape!");
            } else {
                StringBuilder sb = new StringBuilder();
                Stack<Integer> st = new Stack<>();
                sb.append("[0,0],");
                while(que.get(ans).pre != -1) {
                    st.push(ans);
                    ans = que.get(ans).pre;
                }
                
                while(!st.isEmpty()) {
                    Node node = que.get(st.pop());
                    sb.append("[").append(node.x).append(",")
                      .append(node.y).append("],");
                    if (node.x == 0 && node.y == m-1) {
                        sb.deleteCharAt(sb.length() - 1);
                    }
                }
                System.out.println(sb.toString());
            }
        }
    }
}
from collections import deque
from typing import List, Tuple

# 方向数组
DIRS = [(-1,0), (0,1), (1,0), (0,-1)]  # 上右下左
VALUES = [3, 1, 0, 1]  # 对应方向的体力消耗

class Node:
    def __init__(self, x: int, y: int, p: int, pre: int = -1):
        self.x = x
        self.y = y
        self.p = p
        self.pre = pre

def solve(n: int, m: int, p: int, mp: List[List[int]]) -> str:
    # BFS搜索
    que = deque([Node(0, 0, p)])
    used = [[False] * m for _ in range(n)]
    used[0][0] = True
    nodes = [Node(0, 0, p)]  # 存储所有节点
    head = 0
    found = False
    ans = 0
    
    while head < len(nodes):
        now = nodes[head]
        head += 1
        
        if now.x == 0 and now.y == m-1:
            found = True
            ans = head - 1
            break
        
        for i, (dx, dy) in enumerate(DIRS):
            tx = now.x + dx
            ty = now.y + dy
            tp = now.p - VALUES[i]
            
            if (0 <= tx < n and 0 <= ty < m and 
                mp[tx][ty] == 1 and not used[tx][ty] and tp >= 0):
                nodes.append(Node(tx, ty, tp, head-1))
                used[tx][ty] = True
    
    if not found:
        return "Can not escape!"
    
    # 重建路径
    path = []
    while nodes[ans].pre != -1:
        path.append(f"[{nodes[ans].x},{nodes[ans].y}]")
        ans = nodes[ans].pre
    
    path.append(f"[0,{0}]")
    return ','.join(path[::-1])

def main():
    while True:
        try:
            n, m, p = map(int, input().split())
            mp = []
            for _ in range(n):
                mp.append(list(map(int, input().split())))
            print(solve(n, m, p, mp))
        except EOFError:
            break

if __name__ == "__main__":
    main()

算法及复杂度

  • 算法:BFS(广度优先搜索)
  • 时间复杂度: - 最坏情况下需要访问所有格子
  • 空间复杂度: - 需要visited数组和队列空间