找到小菇凉 (BFS)

Description

天凉了,小菇凉天天被扇子妈关在家里不让她到处跑。小菇凉觉得很无聊。这天,趁着扇子妈出门,小菇凉偷偷溜出门去玩。因为太久没出门太开心了,小菇凉一不小心就跑到了很远的地方,很晚都没有回家。扇子妈妈很担心,于是找到小光头问他是否看到小菇凉。小光头知道小菇凉会跑到很远的森林里去玩,于是决定帮扇子妈去找小菇凉。天色已经很晚了,小光头希望尽快找到小姑凉。

Input

输入第一行两个整数N,M(1 <= N,M <= 1000)表示森林的大小。 
接下来一个N*M的矩阵由“#”,“.”组成。“#”表示该地为高灌木,小光头不能通过。“.”表示该地为空地,小光头能通过。地图上仅有一个“A”表示小姑凉的位置,一个“B”表示小光头的位置。

Output

当小光头能看到小菇凉时(即小光头和小菇凉在同行或同列,中间没有障碍时)表示小光头找到了小菇凉。若小光头能找到小菇凉,输出最快找到小菇凉的时间。若不能找到小菇凉,输出No!!!

Sample Input

5 5
...A#
##...
..B##
#####
.....

Sample Output

2

思路:

bfs .典型的BFS,最开始我们学习BFS迷宫问题是找到目标点,停止扩展,任务结束,退出循环。

本题就是把结束条件换成 同行或同列 && 中间不能有障碍物。那么主要任务是写个check函数判断找到了。

我的方法是从上下左右四个方向进行枚举。

#include <cstdio>  
#include <queue>  
using namespace std; 
const int inf = 0x3f3f3f3f;   
int a[1005][1005];   
int book[1005][1005];
int dx[]={0, 1, 0, -1};  
int dy[]={1, 0, -1, 0};   
int n, m;  
struct node {  
    int x, y, s;
    node(int _x = 0, int  _y = 0, int _s = 0) : x(_x), y(_y), s(_s) {}  
};  
int check(int tx,int ty,int p,int q)  {  
    int x, y;  
    x = tx; y = ty;  
    while(a[x][y] != 1 && x >= 1 && x <= n && y >= 1 && y <= m) {  
    	if(x == p && y == q) return 1;
     	x--;  
    }  
    x = tx; y = ty;  
   while(a[x][y] != 1 && x >= 1 && x <= n && y >= 1 && y <= m) {  
		if(x == p && y == q) return 1;
        x++;  
    }  
    x = tx; y =ty;  
    while(a[x][y] != 1 && x >= 1 && x <= n && y >= 1 && y <= m) {  
      if(x == p && y == q) return 1;
       y--;  
    }  
    x = tx; y = ty;  
   while(a[x][y] != 1 && x >= 1 && x <= n && y >= 1 && y <= m) {  
   		if(x == p && y == q) return 1;
        y++;  
    }     
    return 0;  
}  
int distance(int sx,int sy,int ex,int ey)  {   
    int flag=0;    
    queue<node> q; 
    q.push(node(sx, sy, 0));  
    book[sx][sy]=1;  
    while(!q.empty())  {  
        node now = q.front();  
        q.pop();  
        for(int k = 0; k <= 3; k++) {  
            int tx = now.x + dx[k];  
            int ty = now.y + dy[k];  
            if(tx < 1 || tx > n || ty < 1 || ty > m)continue;  
            if(a[tx][ty] == 0 && book[tx][ty] == 0) {  
                book[tx][ty]=1;   
                q.push(node(tx, ty, now.s + 1));  
            }  
            if(check(tx, ty, ex, ey))  {  
                flag = 1;  
                break;  
            }  
        }  
        if(flag) return now.s + 1;   
     }  
    return inf;  
}  
  
int main()  {    
    char ch;    
    int x1,y1,x2,y2;  
    scanf("%d%d",&n,&m);  
    for(int i = 1; i <= n; i++)  
        for(int j = 1; j <= m; j++) {  
            scanf(" %c",&ch);  
            if(ch == '.')
            	a[i][j] = 0;   
            else if(ch == '#')
            	a[i][j] = 1;    
            else if(ch =='B') {  
                a[i][j] = 0;  
                x1 = i;  
                y1 = j;  
            }  
            else if(ch == 'A') {  
                a[i][j] = 0;  
                x2 = i;  
                y2 = j;  
            }   
        }
        int time = distance(x1, y1, x2, y2);  
        if(time == inf)   
            printf("No!!!");  
        else  
            printf("%d\n",time);  
        return 0;  
} 





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值