[Learning] wide search is better to come take a look Patrol Robot UVA - 1600 (condition shortest; bfs Advanced)

topic

Problem
A robot has to patrol around a rectangular area which is in a form of m × n grid (m rows and n columns). The rows are labeled from 1 to m. The columns are labeled from 1 to n. A cell (i, j) denotes the cell in row i and column j in the grid. At each step, the robot can only move from one cell to an adjacent cell, i.e. from (x, y) to (x + 1, y), (x, y + 1), (x − 1, y) or (x, y − 1). Some of the cells in the grid contain obstacles. In order to move to a cell containing obstacle, the robot has to switch to turbo mode. Therefore, the robot cannot move continuously to more than k cells containing obstacles.
Your task is to write a program to find the shortest path (with the minimum number of cells) from cell (1, 1) to cell (m, n). It is assumed that both these cells do not contain obstacles.
Input
The input consists of several data sets. The first line of the input file contains the number of data sets which is a positive integer and is not bigger than 20. The following lines describe the data sets.
For each data set, the first line contains two positive integer numbers m and n separated by space (1 ≤ m, n ≤ 20). The second line contains an integer number k (0 ≤ k ≤ 20). The i-th line of the next m lines contains n integer aij separated by space (i = 1, 2, . . . , m; j = 1, 2, . . . , n). The value of aij is ‘1’ if there is an obstacle on the cell (i, j), and is ‘0’ otherwise.
Output
For each data set, if there exists a way for the robot to reach the cell (m, n), write in one line the integer number s, which is the number of moves the robot has to make; ‘-1’ otherwise.
Sample Input
3
2 5
0
0 1 0 0 0
0 0 0 1 0
4 6
1
0 1 1 0 0 0
0 0 1 0 1 1
0 1 1 1 1 0
0 1 1 1 0 0
2 2
0
0 1
1 0
Sample Output
7
10
-1
Source
https://vjudge.net/problem/UVA-1600

Probably translate:

M * n in the robot maze, starting from the point (1,1) to the end point (m, n), wherein each one orientation only moved one space to the left and down, but he can continuously through k (may be zero) wall, with 0 and 1 map depicted, represents accessible 0, it indicates there is a wall, if we reach the end, the output of the minimum number of steps; otherwise outputs "-1."

analysis:

BUFF k robot has continuously through the wall, then naturally caused some problems, complete address these issues, the topic will be solved:

1. When the robot in a position to search for a position (not standing still ha), no wall of course to go, but if there is a wall it?
A: Of course go wide search requires continuous traverse the whole map, the map is not (20 * 20), without compression also through all possible

2. If the robot and the end point are separated by only a wall, a wall wearing another step on to, and if a detour is likely not the shortest, if not impossible to reach; but if the wall or across a number of small k, through the wall it is not desirable, then detour but is the only option, then how do we choose?
A: First, we want to reach through all the possible places of arrival and the number of possible position through the wall, through several walls and therefore the number of walking no one is currently a higher priority, but in the end the number of steps in order to reach the finish line, whichever is less used.
How to record it? Because of the "continuous" through the wall of the restrictions, we need to find ways to record the number on a path at some point have been continuous through the wall, the structure is a good choice (to open variables like).
At the same time also can not meet the demand with only a two-dimensional array of recording the number of steps again, and we can open a three-dimensional array of records "in the coordinates through the consecutive number of steps required bs wall, and then press the minimum update in the search process like.
In other words, it may also exist (x, y, 1) ( x, y, 0) two structures, the number of steps if they are different, there is no higher or lower within a queue, because we have to traverse all might

3. Once the search immediately to output it? Will there better solutions in the queue?
A: There may exist within the queue times less than the current through the wall of the path, but there can be no less than the current number of steps of the position, that is, the number of steps all the difference in the queue structure must be ≤1, so traverse like to direct output end

4. Note that "continuous" concept, if you have to wear a continuous wall next 2 does not pass through the wall, then was continuously interrupted

Further details with reference to the code

achieve

/* 头文件略 */
using namespace std;
const int INF = 0x3f3f3f3f;
int dx[] = {-1, 0,0,1}; //数组记录四个方位
int dy[] = { 0,-1,1,0};
struct P {
    int x, y; //当前位置横纵坐标
    int bs; //当前位置已连续穿墙数
    P(int x = 0, int y = 0, int bs = 0):
        x(x), y(y), bs(bs) {}
};
int r, c, k;
inline bool in_border (int mx, int my) { //判断出界
    return mx>=0 && mx<r && my>=0 && my<c;
}
int d[25][25][25]; //d[x][y][bs] 表示到达(x,y)位置连续穿bs面墙所需步数 这个是随着搜索而更新的
int s[25][25]; //记录地图
void bfs() {
    memset(d, INF, sizeof(d)); //当然了初始值是要有的
    d[0][0][0] = 0; //终点和起点重合就不用走了
    queue<P> q;
    q.push(P(0, 0, 0));
    while(!q.empty()) {
        P tmp = q.front(); q.pop();
        if(tmp.x == r-1 && tmp.y == c-1) { //如果到了直接输出就好
            cout << d[r-1][c-1][tmp.bs] << endl;
            return;
        }
        for(int i = 0; i < 4; i++) {
            int mx = tmp.x + dx[i], my = tmp.y + dy[i]; //下一步
            if(!in_border(mx, my)) continue;
            if(s[mx][my]) { //下一步要穿墙
                if(tmp.bs == k) continue; //穿不动了
                if(d[mx][my][tmp.bs+1] > d[tmp.x][tmp.y][tmp.bs] + 1) {
                    d[mx][my][tmp.bs+1] = d[tmp.x][tmp.y][tmp.bs] + 1; //更新数组
                    q.push(P(mx, my , tmp.bs+1));
                }
            }
            else { //下一步无障碍
                if(d[mx][my][0] > d[tmp.x][tmp.y][tmp.bs] + 1) {
                    d[mx][my][0] = d[tmp.x][tmp.y][tmp.bs] + 1; //鉴于“连续” 既然无障碍也就不连续了
                    q.push(P(mx, my , 0));
                }
            }
        }
    }
    cout << "-1" << endl; //遍历所有可能 机器人仍无法抵达终点
}
int main() {int T; cin >> T; getchar();
    while(T--) {
        cin >> r >> c >> k;
        for(int i = 0; i < r; i++)
            for(int j = 0; j < c; j++)
                cin >> s[i][j];
        bfs();
    }
    return 0;
}

Go China! ! ! Ei (≧ ◇ ≦) ㄏ

Published 54 original articles · won praise 43 · views 1933

Guess you like

Origin blog.csdn.net/Jungle_st/article/details/104766975