LintCode1563. Shortest path to the destination (BFS经典题)

本文详细解析了一种基于广度优先搜索(BFS)的最短路径算法,用于解决二维地图上的路径寻找问题。通过遍历地图上的节点,算法能够找到从起点到目标点的最短路径,并返回路径长度。文章提供了具体的实现代码,展示了如何有效避免重复访问已检查过的节点。

原题如下:
1563. Shortest path to the destination
Given a 2D array representing the coordinates on the map, there are only values 0, 1, 2 on the map. value 0 means that it can pass, value 1 means not passable, value 2 means target place. Starting from the coordinates [0,0],You can only go up, down, left and right. Find the shortest path that can reach the destination, and return the length of the path.

Example
Given:

[
[0, 0, 0],
[0, 0, 1],
[0, 0, 2]
]
Return: 4

Notice
1.The map must exist and is not empty, there is only one target

解法1:BFS.
注意:

  1. 此题类似骑士遍历题,但骑士遍历题的检查target是检查坐标,这题是检查value。所以如果在struct Point里面加上value这一项要确保target=2的值没有被改掉。
  2. 此题不需要visited map,因为可以简单的将targetMap[i][j]设为1,这样下次就不用再访问了。
  3. In the validPlace(), 要确保先检查p.x和p.y的范围,然后再检查grid[p.x][p.y]的值,不然就segment fault.

代码如下:

class Solution {
public:
    struct Point {
        int x;
        int y;
        Point(int row, int col) : x(row), y(col) {}
    };
    
    /**
     * @param targetMap: 
     * @return: nothing
     */
    int shortestPath(vector<vector<int>> &targetMap) {
        vector<int> dirX = {1, 0, -1, 0}; //east, north, west, south
        vector<int> dirY = {0, -1, 0, 1}; //east, north, west, south
     //   vector<vector<int>> visited(targetMap.size(), vector<int>(targetMap[0].size(), 0));

        queue<Point> q;
        q.push(Point(0, 0));
        int pathLen = 0;
        
        while(!q.empty()) {
            int qSize = q.size();
            for (int i = 0; i < qSize; ++i) {
                Point p = q.front();
                q.pop();
                
                if (targetMap[p.x][p.y] == 2) return pathLen;
                
                targetMap[p.x][p.y] = 1; //set as visited
                
                for (int j = 0; j < 4; ++j) {
                    Point neighborNode = Point(p.x + dirX[j], p.y + dirY[j]);
                    if (validPlace(targetMap, neighborNode)) 
                        q.push(neighborNode);
                }
            }
            pathLen++;
        }
        
        return -1;
    }

private:
    bool validPlace(vector<vector<int>> &grid, Point &p) {
        return (p.x >= 0 && p.x < grid.size() && p.y >= 0 && p.y < grid[0].size()) &&
               (grid[p.x][p.y] >= 0) &&
               (grid[p.x][p.y] != 1);
    }
};
c++解,代码没有注释,可从上网查询,输出必须符合样例,本有8个测试点,请得满分。 T-2 Breaking Through 分数 35 作者 陈越 单位 浙江大学 In a war game, you are given a map consists of n×n square blocks. Starting from your current block, your task is to conquer a destination block as fast as you can. The difficulties are not only that some of the blocks are occupied by enemies, but also that they are shooting in some directions. When one is shooting in some direction, the whole row/column in that direction will be covered by fire, unless there is another enemy blocking the way. You must make sure that you are not shot on the way to your destination. However, it is very much likely, at the very beginning, that this task is impossible. So you must follow the following instructions: Step 1: find the shortest path from the starting block to the destination, avoiding all the enemy blocks. The path length is the number of blocks on the way, not including the starting block. If this path is not unique, select the smallest index sequence – that is, all the blocks are indexed from 1 to n 2 , starting from the upper-left corner, and row by row till the lower-right corner. An index sequence is an ordered sequence of the block indices from the starting block to the destination. One sequence { s,u 1 ​ ,⋯,u k ​ ,d } is said to be smaller than { s,v 1 ​ ,⋯,v k ​ ,d }, if there exists 1≤p≤k such that u i ​ =v i ​ for i<p and u p ​ <v p ​ . Step 2: if some of the blocks along the selected shortest path is covered by fire, conquer and clear the nearest reachable enemy block that are firing at the path (in case that such a block is not unique, take the one with the smallest index). Then take that block as the starting position, goto step 1. Keep in mind that you must always make sure that you are not shot on the way. If step 2 is impossible, then the game is over. Otherwise, keep going until you finally conquer the destination. Input Specification: Each input file contains one test case. For each case, the first line contains a positive integer n (3≤n≤100), which is the size of the map. Then n lines follow, each gives n numbers. Each number describes the status of the corresponding block: 0 means the block is clear; 1, 2, 3, or 4 means the block is occupied by an enemy, who will shoot toward up, down, left, and right, respectively; 5 means the block is your starting position; 6 means the block is your destination. All the numbers in a line are separated by a space. Note: You can never cross any of the boundaries of the map. When an enemy is shooting from block A in direction B, every block starting from A in direction B will be covered by fire, untill the boundary is reached, or another enemy block is encountered. The enemies will never kill each other. Only you will get killed if you step into a block that is covered by fire. It is guaranteed that there is no more than n enemy blocks, and your starting position is not on fire. Output Specification: Print in a line the path length for you to reach the last block from your starting position, and the block number. The two numbers must be separated by 1 space. In the next line, print Win if the destination is reached, or Lose if not. Sample Input 1: 6 6 2 0 0 0 0 0 0 0 0 0 0 0 4 0 0 0 0 0 0 0 0 1 0 0 0 0 3 5 0 4 0 0 0 0 0 Sample Output 1: 10 1 Win Hint: The movements are shown by the following figures 14. Figure 1 shows how the blocks are numbered. Figure 2 shows the initial status of the map, where the player’s position is green, enemy blocks are black, and red blocks are covered by fire. At the very beginning the shortest path was 29->30->24->18->12->11->10->9->8->7->1, but the path was covered by fire shooting from blocks 23, 14 and 2. Since the enemy block 23 is the nearest reachable one, it was cleared with path length 1. Now starting from block 23, the shortest path was 23->17->11->10->9->8->7->1, but the path was covered by fire shooting from blocks 14 and 2. Since the enemy block 14 is covered by fire from block 2, taking block 2 now is the only option. So next, block 2 is cleared with path length 8 (crossing the destination). Finally we can get to the destination from block 2 to 1. Sample Input 2: 4 5 0 2 0 0 0 0 0 0 1 0 0 4 0 6 3 Sample Output 2: 6 3 Lose Hint: The movements are shown by the following figures 5~8. Figure 5 shows how the blocks are numbered. Figure 6 shows the initial status of the map. At the very beginning the shortest path was 1->2->6->7->11->15, but the path was covered by fire shooting from blocks 3, 10, 13 and 16. Since the enemy block 10 is the nearest reachable one, it was cleared with path length 3. Now starting from block 10, the shortest path was 10->11->15, but the path was covered by fire shooting from blocks 3, 13 and 16. Since the enemy blocks 13 and 16 are covered by fire from each other, taking block 3 now is the only option. So next, block 3 is cleared with path length 3. Now it is clear that there is no way to conquer the destination, since block 15 is fired by 13 and 16, yet we cannot clear any of them without getting fired. Hence the last block we can reach is 3. steps2.png 代码长度限制 16 KB 时间限制 400 ms 内存限制 64 MB 栈限制 8192 KB
08-23
A player wants to press the direction buttons as little as possible so that both frogs arrive at the destination to finish the game. Find the minimum number of times the player pressed the buttons to finish the game. If the frog or green frog cannot arrive at the destination, output -1. [Figure] For example, let's look at the case where a grid with six rows and six columns is given. The frog is located at (6, 1), the green frog is located at (1, 6), and the destination is (2, 3) as shown in the [Figure]. Walls are marked with #. First, the frog arrives at the destination first by moving eight times as shown on the left side of the [Figure], and the green frog moves to the opposite direction at the same time and is located at (6, 4). Next, as shown on the right side of the [Figure], when the green frog arrives at the destination by moving it five times, you pressed the buttons 13 times for both frogs to arrive at the destination. This is the minimum number of times you press the buttons. [Constraints] 1. N and M are integers from 2 to 40. 2. R1, R2, and R3 are integers from 1 to N. 3. C1, C2, and R3 are integers from 1 to M. 4. Both frogs cannot be at the same location while they are moving. 5. Walls are not the start and destination of both frogs, and the start positions of the two frogs are not their destinations. [Input] First, the number T of test cases is given, followed by T test cases. On the first line of each test case, N and M are given, separated by spaces. On the next line, R1, C1, R2, C2, R3, and C3 are given in the order, separated by spaces. Over the next N lines, a string of length M is given..” represents a position in the grid to which both frogs can move, and “#” represents a wall. [Output] Output one line per test case. For each test case, output “#x” (where x is the number of the test case, starting from 1), leave a space, and then output the answer of the relevant test case. [Example of Input and Output] (Input) 1 6 6 6 1 1 6 2 3 ....#. .#..#. .#..#. .#..#. .#.##. .#....
09-16
基于NSGA-III算法求解微电网多目标优化调度研究(Matlab代码实现)内容概要:本文围绕基于NSGA-III算法的微电网多目标优化调度展开研究,重点介绍了如何利用该先进多目标进化算法解决微电网系统中多个相互冲突的目标(如运行成本最小化、碳排放最低、供电可靠性最高等)的协同优化问。文中结合Matlab代码实现,详细阐述了NSGA-III算法的基本原理、在微电网调度模型中的建模过程、约束条件处理、目标函数设计以及仿真结果分析,展示了其相较于传统优化方法在求解高维、非线性、多目标问上的优越性。同时,文档还提供了丰富的相关研究案例和技术支持背景,涵盖电力系统优化、智能算法应用及Matlab仿真等多个方面。; 适合人群:具备一定电力系统基础知识和Matlab编程能力的研究生、科研人员及从事能源优化领域的工程技术人员;尤其适合正在进行微电网调度、多目标优化算法研究或撰写相关论文的研究者。; 使用场景及目标:①掌握NSGA-III算法的核心思想及其在复杂能源系统优化中的应用方式;②学习如何构建微电网多目标调度模型并利用Matlab进行仿真求解;③为科研项目、毕业论文或实际工程提供算法实现参考和技术支撑。; 阅读建议:建议读者结合文中提供的Matlab代码实例,逐步调试运行并深入理解算法流程与模型构建细节,同时可参考文档中列出的其他优化案例进行横向对比学习,以提升综合应用能力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值