BFS is a problem

About BFS points:
1, if the coordinate system can be turned into a pattern, the structure can be used to store its value x, y values ​​and the number of steps. (And now generally open Next, the structure for taking out now queue inside) next to the vertical and horizontal motion calculation, and push to the queue.
2, in the use of the queue, commonly used functions (push, front, size, empty, pop, etc.), especially when the pop remember queue inside front body structure, which is the contents of the queue to use to store orderly take out.
3, when the press-fitting point to the queue is reasonable to judge, write a check function for determining, based on whether the boundary is determined, and whether intended Matter requirements.
4, entitled A planned "Portal" and will not affect the step, in determining the overly complex function can be written so as not to be confused thinking. May be an array of recording at critical points, you can start and 10% of the meaning of the questions array when the array of open (meaning of the questions: a <= 100 Opening a [110]).
5, when the compression movement, to open a two-dimensional array can be moved around, the meaning of the questions, the general structure is moved next use.



BFS example:
A plan
Poor Princess again after being abducted by the devil to save time and again by the Knights back, and now, unfortunately, she once again face the test of life. Beelzebub has issued the news that the princess would eat at T moment, because he listened to rumors that the princess eating meat can live forever. It is anxious old king, the world is told to recruit warriors to rescue the princess. But the princess has long been accustomed to, she was convinced Zhiyong knight LJ certainly be able to get her out.
It is now reported spy, princess locked in a maze of two layers, the inlet labyrinth is S (0,0,0), the position indicated by P Princess, represented by temporal conveyor #, * denotes a wall, the ground a. representation. Knights entered the space-time machine will be transmitted to another relative position, but if the position is to the wall, then knights will be killed. Knights in a layer can only move around, move one space each time spend 1. Moving only through time and space between the layers of the conveyor, and does not require any time.
Input a first input line C C represents the total test data, the test data for each of the previous row has three integers N, M, T. N, M maze size N * M (1 <= N, M <= 10). T is as intended. Before the next arrangement of N * M represents the labyrinth of the first layer, the arrangement of N * M represents the labyrinth of the second layer. Output If the Cavs were able to find the princess at a time T outputs "YES", otherwise a "NO". Sample Input
1
5 5 14
S*#*.
.#...
.....
****.
...#.

..*.P
#.*..
***..
...*.
*.#..
Sample Output
YES

#include <stdio.h>
#include <cstring>
#include <queue>
using namespace std;

struct node
{
    int x,y,floor;
    int step;
};

int t,n,m,lim;
int s[3],e[3];
int to[4][2] = {1,0,0,1,-1,0,0,-1};
char map[2][15][15];
int use[2][15][15];

int check(int floor,int x,int y)
{
    if(x<0 || y<0 || x>=n || y>=m)
        return 1;
    if(map[floor][x][y]=='*')
        return 1;
    return 0;
}

void BFS()
{
    memset(use,0,sizeof(use));
    node a,next;
    queue<node> Q;
    int i,j,k;
    a.floor = s[0];
    a.x = s[1];
    a.y = s[2];
    a.step = 0;
    use[s[0]][s[1]][s[2]] = 1;
    Q.push(a);
    while(!Q.empty())
    {
        a = Q.front();
        Q.pop();
        if(a.floor == e[0] && a.x == e[1] && a.y == e[2])
        {
            printf("YES\n");
            return ;
        }
        if(a.step>=lim)
            break;
        for(i = 0; i<4; i++)
        {
            next = a;
            next.x+=to[i][0];
            next.y+=to[i][1];
            next.step++;
            if(check(next.floor,next.x,next.y))
                continue;
            if(use[next.floor][next.x][next.y])
                continue;
            use[next.floor][next.x][next.y] = 1;
            if(map[next.floor][next.x][next.y] == '#')
            {
                next.floor=!next.floor;
                if(check(next.floor,next.x,next.y))
                    continue;
                if(use[next.floor][next.x][next.y])
                    continue;
                if(map[next.floor][next.x][next.y] == '*' || map[next.floor][next.x][next.y] == '#')
                    continue;
                use[next.floor][next.x][next.y] = 1;
            }
            if(next.floor == e[0] && next.x == e[1] && next.y == e[2])
            {
                printf("YES\n");
                return ;
            }
            Q.push(next);
        }
    }
    printf("NO\n");
}

int main()
{
    int i,j,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&lim);
        for(int k=0;k<2;k++)
        {
            for(i=0;i<n;i++)
            {
                scanf("%s",map[k][i]);
                for(j = 0; j<m; j++)
                {
                    if(map[k][i][j] == 'S')
                    {
                        s[0] = k,s[1] = i,s[2] = j;
                    }
                    else if(map[k][i][j] == 'P')
                    {
                        e[0] = k,e[1] = i,e[2] = j;
                    }
                }
            }
        }
        BFS();
    }

    return 0;
}

Note: If the same position two is the portal, it will unlimited transfer; 
ideas: 
1  because the position is to the wall, then knights will be killed, if the same position two layers are transferred doors, it will unlimited transfer, we can do pre-advance, these two cases are set to point the wall, it will not interfere with the back of the search; 
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
   int t,x,y,z;
};
char map[15][15][5];
int mark[15][15][5];
int n,m,t,flag;
int dx,dy,dz;
int vis[4][2]={0,1,0,-1,1,0,-1,0};
int ok(int x,int y,int z)
{
    if(x>=1&&x<=n&&y>=1&&y<=m&&map[x][y][z]!='*')
       return 1;
    else
       return 0;
}
void bfs()
{
    node q,p;
    q.x=1,q.y=1,q.z=1,q.t=0;
    queue<node>que;
    que.push(q);
    while(que.size())
    {
        q=que.front();
        que.pop();
        if(q.t>t)
           return;
        if(q.x==dx&&q.y==dy&&q.z==dz)
        {
            flag=q.t;
            return;
        }
        for(int i=0;i<=3;i++)
        {
            p.x=q.x+vis[i][0];
            p.y=q.y+vis[i][1];
            if(ok(p.x,p.y,q.z)&&!mark[p.x][p.y][q.z])
            {
                mark[p.x][p.y][q.z]=1;
                if(map[p.x][p.y][q.z]=='#')
                {
                    if(q.z==1)
                       p.z=2;
                    else
                       p.z=1;
                    mark[p.x][p.y][p.z]=1;
                }
                else
                  p.z=q.z;
                p.t=q.t+1;
                que.push(p);
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        flag=0;
        scanf("%d%d%d",&n,&m,&t);
        getchar();
        for(int j=1;j<=2;j++)
        {
            for(int i=1;i<=n;i++)
            {
                for(int k=1;k<=m;k++)
                {
                    scanf("%c",&map[i][k][j]);
                    if(map[i][k][j]=='P')
                       dx=i,dy=k,dz=j;
                }
                getchar();
            }
            getchar();
        }
        for(int i=1;i<=n;i++)
           for(int j=1;j<=m;j++)
           {
               if(map[i][j][2]=='#'&&map[i][j][1]=='#')
                  map[i][j][1]='*',map[i][j][2]='*';
               if(map[i][j][2]=='#'&&map[i][j][1]=='*')
                  map[i][j][2]='*';
               if(map[i][j][1]=='#'&&map[i][j][2]=='*')
                  map[i][j][1]='*';
           }
        memset(mark,0,sizeof(mark));
        mark[1][1][1]=1;
        bfs();
        if(flag)
           printf("YES\n");
        else
           printf("NO\n");

    }
}

analysis

Only need to pay attention to the issue of transfer between the double

If the '#' next level is ' ' so this layer '#' will become '*  '

Additional point to note is that the problem on two layers

If the layer is another layer is ff ff ^ 1;

Code + Comment

#include <iostream>
#include <queue>
#include<cstring>
using namespace std ;
typedef struct L{
    int x,y,f ;
    int step ;
}L ;
int n,m,t ;
char map[2][11][11] ;
int vis[2][11][11] ;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}} ;// 四个移动方向
int flag ;

void bfs()
{
    memset(vis,0,sizeof(vis)) ;
    flag=0 ;
    L now,next ;
    queue <L> q ;//新建队列
    now.x=now.y=now.f=now.step=0 ;
    q.push(now) ;
    vis[0][0][0]=1 ;
    while(!q.empty())
    {
        now=q.front() ;
        q.pop() ;
        if(map[now.f][now.x][now.y]=='P' && now.step<=t)//如果搜寻到 目标值且步数少于等于最大值
        {
            flag=1 ;
            return ;//标记 返还
        }
        if(map[now.f][now.x][now.y]=='P')//如果找到但是不是最大值  直接返回 无要求解(bfs默认为最小)
        {
            return ;
        }
        for(int i=0;i<4;i++)
        {
            next.x=now.x+dir[i][0] ;
            next.y=now.y+dir[i][1] ;
            next.f=now.f ;
            int xx=next.x ;
            int yy=next.y ;
            int ff=next.f ;//变换之后的三维坐标
            if(xx<0 || xx>=n)//判断是否越界
                continue ;
            if(yy<0 || yy>=m)
                continue ;
            if(map[ff][xx][yy]=='*')//判断是否是星号
                continue ;
            if(map[ff][xx][yy]=='#' && map[ff^1][xx][yy]=='*')//如果是电梯 那么他转换后是否是星号
                continue ;
            if(map[ff][xx][yy]=='#' && map[ff^1][xx][yy]=='#')//同样是电梯的也不行
                continue ;    
            if(!vis[ff][xx][yy] && map[ff][xx][yy]=='#' && vis[ff^1][xx][yy]==0)
            {
                vis[ff][xx][yy]=1 ;
                next.f^=1 ;//如果是电梯 转换到另外一层
                vis[next.f][xx][yy]=1 ;//标记
                next.step=now.step+1 ;//不失加一
                q.push(next) ;//递归
            }
            if(!vis[ff][xx][yy] && map[ff][xx][yy]!='#')
            {
                vis[ff][xx][yy]=1 ;//标记
                next.step=now.step+1 ;//步数加一
                q.push(next) ;//递归
            }
        }
    }
}
int main(void)
{
    int c ;
    scanf("%d",&c) ;
    while(c--)
    {
        scanf("%d%d%d%*c",&n,&m,&t) ;
        for(int i=0;i<2;i++)
        {
            for(int j=0;j<n;j++)
                scanf("%s",map[i][j]) ;
            getchar() ;
        }
        bfs() ;
        if(flag)
            puts("YES") ;
        else
            puts("NO") ;
    }
    return 0 ;
}

Published 37 original articles · won praise 12 · views 6528

Guess you like

Origin blog.csdn.net/weixin_38960774/article/details/79410321