zzulioj 1726 Labyrinth (BFS)

1726: Labyrinth

Time Limit:  1 Sec   Memory Limit:  128 MB
Commits:  985   Resolved:  150
[ Commit ][ Status ][ Discussion Board ][Assert By: admin ]

Topic description

In many  RPG (Role-playing Games)  games, the maze is often a very complicated game link. Generally speaking, we need to spend a lot of time trying different paths when walking through the maze . But with the help of algorithms and computers, can we have a faster way to solve this problem? We can try something.

Now we have a maze with  N  rows and  M  columns. If each square of the maze is an open space, people can stand, but not if it is an obstacle. On a grid, we can move to its adjacent  8  open spaces in one step, but cannot leave the border of the map or cross the gap between two obstacles. The image below is an example of a move rule.

In order to leave the maze, we also need to trigger all the traps in the maze.  There are a total of K  organs in the maze, and each organ falls on a different open space. If we reach the grid where a trap is located, the trap will be triggered automatically and disappear immediately after triggering .  Our goal is to trigger all K              traps in sequence , and when the last trap is triggered, we can leave the maze.

Now we have got the maze map and know the location of all the obstacles and traps. Initially, we are located on a non- obstacle . Please calculate the minimum number of steps we need to move to leave the maze?

enter

The first line of input is the number of groups T of test data  (T ≤ 20) .

For each set of test data: the first row contains the map's number of rows  N (2 ≤ N ≤ 100) , the number of columns  M (2 ≤ M ≤ 100)  and the number of organs  K (1 ≤ K ≤ 10) . Next  N  lines, each line contains  M  characters, where the characters '#'  represent obstacles and '.'  represent empty spaces. The next line describes our initial position  (x, y) , which means we start on the grid at row  x  and column  y  . This grid is guaranteed to be an open space. The next  K  lines, each of which gives the position of an organ. All traps will not appear on obstacles, and no two traps will appear in the same clearing.  We need to trigger all K  organs in the order given by the input .  

output

For each set of test data, output the minimum number of steps required to leave the maze. If you can't leave the maze anyway, output  -1 .

sample input

3
3 3 2
...
...
...
1 1
1 3
2 2
3 3 1
...
.#.
...
1 1
3 3
2 3 1
..#
.#.
1 1
2 3

Sample output

3
3
-1

source

The conditions in the question are not clear (resulting in too many pits), and this question is too much to think about. I haven't done anything similar, so I don't really think about its implicit conditions. Note that except for the first one, the rest cannot appear at the starting point.

/*
机关不能当作障碍,像下面这样对角线也能走
但是当做#后,就不能走了 
.*
#.
 
*/ 
#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
char mat[105][105];
int vis[105][105];
int x1,y1;
int n,m,k,sum;
int f[8][2]={0,1,1,0,-1,0,0,-1,1,1,-1,1,1,-1,-1,-1};
int flag;
struct node{
    int x,y;
    int temp;
};
struct key{
    int a,b;
}ke[15];
void bfs(int x,int y,int num)//起点,第num个机关 
{
    memset(vis,0,sizeof(vis));
    node s,t;
    queue<node>q;
    vis[x][y]=1;
    s.x=x;
    s.y=y;
    s.temp=0;
    q.push(s);
    while(!q.empty()&&!flag)
    {
        t=q.front();
        q.pop();
        if(t.x==ke[num].a&&t.y==ke[num].b)
        {   
            flag=1;
                sum+=t.temp;
                return;
        }
        for(int i=0;i<8;i++)
        {
            s.x=t.x+f[i][0];
            s.y=t.y+f[i][1];
            s.temp=t.temp+1;
            if(s.x<0||s.y<0||s.x>=n||s.y>=m||vis[s.x][s.y]||mat[s.x][s.y]!='.')
            continue;
            if(i==4&&mat[t.x+1][t.y]=='#'&&mat[t.x][t.y+1]=='#')
            continue;
            if(i==5&&mat[t.x-1][t.y]=='#'&&mat[t.x][t.y+1]=='#')
            continue;
            if(i==6&&mat[t.x][t.y-1]=='#'&&mat[t.x+1][t.y]=='#')
            continue;
            if(i==7&&mat[t.x-1][t.y]=='#'&&mat[t.x][t.y-1]=='#')
            continue;
            vis[s.x][s.y]=1;
            q.push(s);
        }
    }
    return;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {   
        flag=0;
        sum=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++)
            scanf("%s",mat[i]);
        scanf("%d%d",&x1,&y1);
        x1-=1;
        y1-=1;
        for(int i=0;i<k;i++)
        {
            scanf("%d%d",&ke[i].a,&ke[i].b);
            ke[i].a-=1;ke[i].b-=1;
            if(ke[i].a==x1&&ke[i].b==y1&&i>0)
            {//除了第一个机关,起点不能有别的机关 
                flag=1;
            }
            //机关用*代替,不能用#代替,二者作用不一样 
            mat[ke[i].a][ke[i].b]='*';
        }
        if(flag)
        {
            printf("-1\n");
            continue;
        }
        mat[ke[0].a][ke[0].b]='.';
        bfs(x1,y1,0);
        for(int i=0;i<k-1&&flag;i++)
        {
            flag=0;
            mat[ke[i+1].a][ke[i+1].b]='.';
            bfs(ke[i].a,ke[i].b,i+1);//新的起点去找第i+1个机关          
        }
        if(!flag) printf("-1\n");
        else printf("%d\n",sum);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324814557&siteId=291194637