地下迷宫(最短路径)

版权声明:原创文章,转载需注明转载出处! https://blog.csdn.net/zhoumingsong123/article/details/81940263

//小青蛙有一天不小心落入了一个地下迷宫,小青蛙希望用自己仅剩的体力值P跳出这个地下迷
//宫。为了让问题简单,假设这是一个n*m的格子迷宫,迷宫每个位置为0或者1,0代表这个位置
//有障碍物,小青蛙达到不了这个位置;1代表小青蛙可以达到的位置。小青蛙初始在(0,0)位置
//,地下迷宫的出口在(0,m-1)(保证这两个位置都是1,并且保证一定有起点到终点可达的路径
//),小青蛙在迷宫中水平移动一个单位距离需要消耗1点体力值,向上爬一个单位距离需要消耗
//3个单位的体力值,向下移动不消耗体力值,当小青蛙的体力值等于0的时候还没有到达出口,
//小青蛙将无法逃离迷宫。现在需要你帮助小青蛙计算出能否用仅剩的体力值跳出迷宫(即达
//到(0,m-1)位置)。
import java.util.*;

class Node implements Comparable<Node> {
    int d = Integer.MAX_VALUE;
    Node previous = null;
    int x;
    int y;
    List<Node> nodeAdj = new ArrayList();

    public int compareTo(Node node) {

        if (this.d > node.d) {
            return 1;
        }
        if (this.d == node.d) {
            return 0;
        }
        return -1;

    }

    public String toString() {
        return "[" + x + "," + y + "]";
    }
}

public class Main {


    private static int n;
    private static int m;

    private static Set<List<Integer>> minPath;
    private static int minPathValue = Integer.MAX_VALUE;


    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        int p = sc.nextInt();
        int v[][] = new int[n][m];

        List<Node> nodeList = new ArrayList();
        Node[][] nodeMap = new Node[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                v[i][j] = sc.nextInt();
                if (v[i][j] == 1) {
                    Node node = new Node();
                    node.x = i;
                    node.y = j;
                    if (i == 0 && j == 0) {
                        node.d = 0;
                    }
                    nodeList.add(node);
                    nodeMap[i][j] = node;

                }


            }
        }

        for (Node node : nodeList) {
            int x = node.x;
            int y = node.y;
            for (int i = 0; i < 4; i++) {
                int tempX = x + addX[i];
                int tempY = y + addY[i];
                if (tempX < 0 || tempX >= n) {
                    continue;
                }
                if (tempY < 0 || tempY >= m) {
                    continue;
                }

                Node nodeAdj = nodeMap[tempX][tempY];
                if (nodeAdj != null) {
                    node.nodeAdj.add(nodeAdj);
                }
            }
        }

        List<Node> solvedList = new ArrayList<>();

        PriorityQueue<Node> pq = new PriorityQueue();

        for (Node node : nodeList) {
            pq.add(node);
        }


        Node endNode = null;
        while (!pq.isEmpty()) {
            Node u = pq.poll();
            solvedList.add(u);
            //System.out.println(u.d);
            if (u.x == 0 && u.y == m - 1) {
                endNode = u;
                //break;
            }
            for (Node nodeAdj : u.nodeAdj) {
                boolean change=songchi(u, nodeAdj);
                if(change)
                {
                    pq.remove(nodeAdj);
                    pq.add(nodeAdj);
                }
            }
        }

        if(endNode.d>p)
        {
            System.out.println("Can not escape!");
        }
        else
        {
            List<Node> path = new LinkedList();
            while (endNode != null) {
                path.add(0, endNode);
                endNode = endNode.previous;


            }

            int count = 0;
            for (Node node : path) {
                if (count == path.size() - 1) {
                    System.out.println(node);
                } else {
                    System.out.print(node + ",");
                }

                count++;
            }
        }




    }

    private static boolean songchi(Node u, Node v) {
        int w = getEdge(u, v);
        if(w==Integer.MAX_VALUE||u.d==Integer.MAX_VALUE)
        {
            return false;
        }
        if (u.d + w < v.d) {
            v.d = u.d + w;
            v.previous = u;
            return true;
        }
        return false;
    }

    private static int getEdge(Node u, Node v) {
        int uX = u.x;
        int uY = u.y;
        int vX = v.x;
        int vY = v.y;
        if (uX - vX == 0 || uY - vY == 0) {
            if (uX == vX && uY == vY) {
                return 0;
            }
            if (uX - vX == 0) {
                if (Math.abs(uY - vY) == 1) {
                    return 1;
                } else {
                    return Integer.MAX_VALUE;
                }
            }
            if (uY - vY == 0) {
                if (uX - vX == 1) {
                    return 0;
                } else if (vX - uX == 1) {
                    return 3;
                } else {
                    return Integer.MAX_VALUE;
                }
            }

            return Integer.MAX_VALUE;


        } else {
            return Integer.MAX_VALUE;
        }


    }


    private static int addX[] = {0, 0, -1, 1};
    private static int addY[] = {1, -1, 0, 0};



}

猜你喜欢

转载自blog.csdn.net/zhoumingsong123/article/details/81940263