CSU1604: SunnyPig(BFS)

Description

SunnyPig is a pig who is much cleverer than any other pigs in the pigpen. One sunny morning, SunnyPig wants to go out of the pigpen to date Mrs. Snail, his beloved. However, it’s terribly tough for a pig to go out of the pigpen because the pigpen is divided into m * n grids with fences which pigs cannot go across. Luckily, there are some doors unlocked on the fences so that SunnyPig can push them open with his nose. Since SunnyPig is a pig, no matter how clever he is, he can never walk upright like human beings. As a result, SunnyPig is not able to pull any doors.
Now give you the map of the pigpen, please calculate the fewest number of doors SunnyPig should push to go out of the pigpen.

Input

The first line there is a number T (0 < T < 100), denoting the number of the test case.
The first line of each test case has only two numbers: m, n.
The following 2*m+1 lines describe the pigpen. Each line has 2*n+1 characters. ’*’ represents a cross point of two fences. ’O’ represents the initial position SunnyPig. ’-’ and ‘|’ represent fences without doors. ’N’, ’S’, ’W’, ’E’ represent the doors SunnyPig can push in the direction of north, south, west and east respectively. And the character of a space represents the place where SunnyPig can go through.

Output

Output the fewest number of doors SunnyPig should push to go out of the pigpen, in other words, the fewest number of doors SunnyPig should push to go out of the border of these grids.
If SunnyPig cannot go out of the pigpen, output -1. Each case, a single line.

Sample Input

2
3 3
*-*N*-*
|O| E E
*S*S*-*
W | E |
*-*S*N*
W W E |
*N*S*N*
4 2
*N*S*
E | W
*S*S*
EOW W
*-*N*
| W E
*-*S*
W E |
*S*S*

Sample Output

2
-1

HINT

Source


题意:一只猪要出去,最少要开几扇门,要注意对于不同的门只能朝一个方向打开,而出口的地方,必然有一扇门
思路:比较水的BFS

#include <iostream> 
#include <stdio.h> 
#include <string.h> 
#include <stack> 
#include <queue> 
#include <map> 
#include <set> 
#include <vector> 
#include <math.h> 
#include <algorithm> 
using namespace std; 
#define ls 2*i 
#define rs 2*i+1 
#define up(i,x,y) for(i=x;i<=y;i++) 
#define down(i,x,y) for(i=x;i>=y;i--) 
#define mem(a,x) memset(a,x,sizeof(a)) 
#define w(a) while(a) 
#define LL long long 
const double pi = acos(-1.0); 
#define Len 200005 
#define mod 19999997 
const int INF = 0x3f3f3f3f; 
#define exp 1e-8 
  
struct node 
{ 
    int x,y,door; 
}; 
  
int mat[1000][1000],n,m,t,vis[1000][1000],sx,sy; 
char str[1005]; 
int to[5][2]= {0,0,0,1,1,0,0,-1,-1,0}; 
  
bool outdoor(int x,int y) 
{ 
    if(x==0||y==0||x==n-1||y==m-1) 
        return true; 
    return false; 
} 
  
bool check(int x,int y) 
{ 
    if(x<0||y<0||x==n||y==m) 
        return true; 
    if(mat[x][y]==-1||vis[x][y]) 
        return true; 
    return false; 
} 
  
void bfs() 
{ 
    queue<node> Q; 
    node a,next; 
    int i,j; 
    a.x = sx; 
    a.y = sy; 
    a.door = 0; 
    vis[sx][sy] = 1; 
    Q.push(a); 
    while(!Q.empty()) 
    { 
        a = Q.front(); 
        Q.pop(); 
        if(outdoor(a.x,a.y)&&mat[a.x][a.y]>0) 
        { 
            printf("%d\n",a.door); 
            return ; 
        } 
        up(i,1,4) 
        { 
            next = a; 
            next.x+=to[i][0]; 
            next.y+=to[i][1]; 
            if(check(next.x,next.y)) continue; 
            if(mat[next.x][next.y]>0 && mat[next.x][next.y]!=i) continue; 
            if(mat[next.x][next.y]>0) 
            { 
                next.door++; 
                if(outdoor(next.x,next.y)) 
                { 
                    printf("%d\n",next.door); 
                    return ; 
                } 
            } 
            vis[next.x][next.y] = 1; 
            Q.push(next); 
        } 
    } 
    printf("-1\n"); 
} 
  
int main() 
{ 
    int i,j,k; 
    scanf("%d",&t); 
    w(t--) 
    { 
        scanf("%d%d\n",&n,&m); 
        n=2*n+1; 
        m=2*m+1; 
        mem(mat,-1); 
        up(i,0,n-1) 
        { 
            gets(str); 
            up(j,0,m-1) 
            { 
                if(str[j]==' '||str[j]=='*') 
                    mat[i][j]=0; 
                else if(str[j]=='-'||str[j]=='|') 
                    mat[i][j]=-1; 
                else if(str[j]=='E') 
                    mat[i][j]=1; 
                else if(str[j]=='S') 
                    mat[i][j]=2; 
                else if(str[j]=='W') 
                    mat[i][j]=3; 
                else if(str[j]=='N') 
                    mat[i][j]=4; 
                else if(str[j]=='O') 
                { 
                    sx = i; 
                    sy = j; 
                    mat[i][j]=0; 
                } 
            } 
        } 
        bfs(); 
    } 
  
    return 0; 
} 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值