hrbust 1948我又回来了 【基础bfs】

我又回来了
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 165(68 users)Total Accepted: 66(58 users)Rating: Special Judge: No
Description

  小辉穿越到了一个很适合他的年代,22222年,他发现虽然他还在地球上,但是这个世界早已不同,经过了世界大破灭,天地大变,已经到了能够修真的年代,他也加入了一个宗门,少林寺。。。一天,小辉想去找小尼姑们一起快乐地玩耍,他知道这个世界存在着传送门,在一瞬间就可以从一个地方传送到另外一个有传送门的地方,他的老毛病(讨厌走路)又犯了,他决定到哪个小尼姑那里的步数最少,就去找哪个小尼姑。

首先给出小辉和小尼姑所在的N*N平面图,如图为6*6平面图。

....#.

.*.#..

..@...

######

.@....

......

有Q个小尼姑,每个小尼姑所在的地点用坐标表示,左上角处坐标为(0,0)。

图中'*'代表小辉所在的位置,图中即(1,1),'.'代表空地,'#'代表不能直接通过的建筑物,'@'代表传送门,传送门不是不能通过的建筑物。

小辉将去找他所能到达的并且离他步数最少的那个小尼姑。

小尼姑的位置可能在除建筑物的任意位置上。

Input

有多组测试数据,处理到文件结束。

对于每组测试数据,第一行是两个整数N(2<=N<=100),Q(1<=Q<=1000),分别代表地区的边长和小尼姑的个数.

接下来输入n*n平面图,代表地区平面图。

然后Q行,每行一个坐标代表小尼姑所在位置。

Output

输出小辉到那个小尼姑的步数,如果没有满足条件的小尼姑,则输出cry,最后换行.

Sample Input
6 3
....#.
.*.#..
..@...
######
.@....
.....@
0 5
1 4
4 1
3 2
*@.
###
..@
0 2
2 1
Sample Output
2
2
 
 
和2188的传送门不同,这个题的传送门可以走也可以不走,所以所有非#点都要存进队列,卡在这里wa了好几波;


#include<bits/stdc++.h>
using namespace std;
int n, k, num;
char maps[105][105];
int step[4][2] = {1, 0, 0, 1, -1, 0, 0, -1};
int vis[105][105];
int black_hole[10005][2];
int mm[1005][2];
struct node
{
    int x, y, step;
} op, uv;
void bfs(int nx, int ny)
{
    memset(vis, 0, sizeof vis);
    vis[nx][ny] = 1;
    op.x = nx;
    op.y = ny;
    op.step = 0;
    queue<node >q;
    q.push(op);
    while(!q.empty())
    {
        op = q.front();
        for(int i = 0; i < k; i++)
        {
            if(op.x == mm[i][0] && op.y == mm[i][1])
            {
                cout << op.step << endl;
                return;
            }
        }
        q.pop();
        for(int i = 0; i < 4; i++)
        {
            uv.x = op.x + step[i][0];
            uv.y = op.y + step[i][1];
            if(uv.x >= 0 && uv.x <= n && uv.y >= 0
                    && uv.y <= n && !vis[uv.x][uv.y]
                    && maps[uv.x][uv.y] != '#')
            {
                if(maps[uv.x][uv.y] == '@')
                {
                    vis[uv.x][uv.y] = 1;
                    for(int j = 0; j < k; j++)
                    {
                        if(uv.x == mm[j][0] && uv.y == mm[j][1])
                        {
                            cout << op.step + 1 << endl;
                            return;
                        }
                    }
                    for(int j = 0; j < num; j++)
                    {
                        if(!vis[black_hole[j][0]][black_hole[j][1]])
                        {
                            uv.step = op.step + 1;
                            uv.x = black_hole[j][0];
                            uv.y = black_hole[j][1];
                            vis[black_hole[j][0]][black_hole[j][1]] = 1;
                            q.push(uv);
                        }
                    }
                }
                vis[uv.x][uv.y] = 1;
                uv.step = op.step + 1;
                q.push(uv);
            }
        }
    }
    cout << "cry" << endl;
    return;
}
int main()
{
    while(cin >> n >> k)
    {
        int xx, yy;
        num = 0;
        memset(black_hole, 0, sizeof black_hole);
        memset(mm, 0, sizeof mm);
        for(int i = 0; i < n; i++)
        {
            scanf("%s", maps[i]);
            for(int j = 0; j < n; j++)
            {
                if(maps[i][j] == '*')
                {
                    xx = i;
                    yy = j;
                }
                if(maps[i][j] == '@')
                {
                    black_hole[num][0] = i;
                    black_hole[num][1] = j;
                    num++;
                }
            }
        }
        for(int i = 0; i < k; i++)
            cin >> mm[i][0] >> mm[i][1];
        n--;
        bfs(xx, yy);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值