Problem B: DFS or BFS? Breadth first search application

Problem B: DFS or BFS?

topic

Description

That's it, the topic is not black.

Give you an 8*8 matrix, your initial position is the lower left square (indicated by'U'), your target position is the upper right square (indicated by'A'), and the remaining 62 squares , If it is'.', it means this square is empty, if it is'S', it means there is a big stone in this square. Okay, now you start from the lower left corner, each time you can move up, down, left, right, upper left, upper right, lower left, and lower right by one square, or you can stay in place, a total of nine actions, in After you perform an action, all the big rocks will drop one square down (if the position of a big stone is (x, y), then the next second will be (x+1, y), but if it is already in If the bottom row is over, it will fall out of the matrix and no longer appear), please note that at any time, you cannot be in the same square with a certain big rock, otherwise the rock will drop you XX.

The question now is: Can you reach the upper right corner safely from the lower left corner? If it can, output "Yes", otherwise, "No".

Input

T->The number of test data groups (T).

For each set of data, enter an 8*8 matrix, followed by a blank row. The description is as above.

Output

For the i-th group of data, please output

Case #i: s (s is a string, if it can be reached, then s is "Yes", otherwise "No")

Sample Input Copy

2
.......A
........
........
........
........
........
........
U.......

.......A
........
........
........
........
.S......
S.......
US......

Sample Output Copy

Case #1: Yes
Case #2: No

Ideas

  • This question uses bfs, and a queue is needed to push and pop points to walk the maze. For details, please see bfs related knowledge
  • Note that using states (set) to determine whether the coordinates and the value of the bottom at that time have ever appeared
    • Because bfs is constantly pushing and pop to save state
    • So it may cause the point A and point B to reach a certain floor and then continue to move to point C at the same time, the situation is repeated
  • Different from the past bfs, this question has a special requirement that every time the stone falls collectively.
    • If you traverse the entire map, it will cause a very large time complexity
    • So instead of modifying the overall map, a better choice is to switch the perspective
    • That is the work done by top[2]. At the same time, top[2] can ensure the upward movement of the point, thus quickly reaching the final point.
  • When you reach the top row, you must reach the end point (just go straight to the left), and return directly.

Code

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <set>
#include <queue>
using namespace std;

char map[8][8];
set<vector<int>> states;//用set判断人物移动后,坐标和bottom的值是否曾经出现过

int flag;

struct point{
    
    
    int x;
    int y;
    int step;
};

bool check(int x,int y,int bottom){
    
    
    //注意判断其上方是否是一个石头
    if(x>=0&&x<=bottom&&y>=0&&y<8&&map[x][y]!='S'&&map[x-1][y]!='S')
        return true;
    return false;
}

void bfs(){
    
    
    states.clear();
    states.insert({
    
    7,0,7});//插入起始点
    queue<vector<int>> Q;//bfs队列
    Q.push({
    
    7,0,7});//插入起始点
    while(!Q.empty()){
    
    //队列为空,bfs结束
        vector<int> top=Q.front();
        if(top[2]==0||top[0]==0){
    
    
            //代表到达最上面一行以上,则安全
            flag=true;
            return;
        }
        Q.pop();//弹出,开始处理
        for(int i=-1;i<=1;i++){
    
    
            for(int j=-1;j<=1;j++){
    
    
                if(check(top[0]+i,top[1]+j,top[2])&&!states.count({
    
    top[0]+i-1,top[1]+j,top[2]-1})){
    
    
                    states.insert({
    
    top[0]+i-1,top[1]+j,top[2]-1});//插入新点
                    Q.push({
    
    top[0]+i-1,top[1]+j,top[2]-1});
                }
            }
        }
    }
}

int main(){
    
    
    int n=0;
    while(scanf("%d",&n)!=EOF){
    
    
        for(int k=1;k<=n;k++){
    
    
            flag=false;
            string input;
            getline(cin,input);
            for(int i=0;i<8;i++){
    
    
                getline(cin,input);
                for(int j=0;j<8;j++){
    
    
                    map[i][j]=input[j];
                }
            }
            bfs();
            printf("Case #%d: %s\n", k, flag ? "Yes" : "No");
        }
        
    }
    return 0;

Guess you like

Origin blog.csdn.net/Cindy_00/article/details/109283339