AcWing 1101. 献给阿尔吉侬的花束【《信息学奥赛一本通》】【bfs】【bfs框架】


一、题目链接

AcWing 1101. 献给阿尔吉侬的花束
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


二、题目分析

(一)算法标签

bfs

(二)解题思路

首先,本题考查宽搜(bfs); 其次, 熟悉bfs框架可以帮我们快速解题,bfs框架如下:
宽搜(bfs)框架

一、 判重数组st[] 一般入队时判重(保证每个点只会入队一次,从而保证时间复杂度是线性的) (特殊情况出队时判重,如A*算法、Dijkstra算法)
二、 queue
  1. queue ← \leftarrow 初始状态
  2. while (queue非空)
   {
     t ← \leftarrow 队头元素
     队头元素出队列
 
     for (扩展t)
     {
       ver ← \leftarrow 新节点
       if (!st[ver])
       {
         ver → \rightarrow 队尾
       }
     }
   }

宽搜(bfs)本质从一个状态扩展到另一个状态。不同宽搜题目的不同点在于状态的定义
主要有两大类, 第一类走迷宫类问题,矩阵的每一个格子是一个状态;第二类是八数码、数独类问题,整个矩阵(一个数组)是一个状态,每次枚举它能变成什么状态


三、AC代码

解法一:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>

using namespace std;

typedef pair<int, int> PII;

#define x first
#define y second

const int N = 210;

char g[N][N];
int dist[N][N];
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

int T, n, m;

int bfs(PII start)
{
    // 初始化dist数组(同时充当st数组)
    memset(dist, -1, sizeof dist);
    dist[start.x][start.y] = 0;
    // 初始化queue
    queue<PII> q;
    q.push(start);
    
    while (!q.empty())  // 队列非空
    {
        auto t = q.front(); // 取队首元素
        q.pop();    // 队首元素出队列
        
        for (int i = 0; i < 4; i ++ )   // 扩展首元素
        {
            int x = t.x + dx[i], y = t.y + dy[i];
            if (x < 0 || x >= n || y < 0 || y >= m) continue;   // 越界
            if (g[x][y] == '#') continue;   // 障碍物
            if (dist[x][y] != -1) continue; // 未被遍历
            
            dist[x][y] = dist[t.x][t.y] + 1;
            
            if (g[x][y] == 'E') return dist[x][y];
            
            q.push({x, y});
        }
    }
    return -1;
}
int main()
{
    cin >> T;
    while (T -- )
    {
        cin >> n >> m;
        for (int i = 0; i < n; i ++ ) scanf("%s", g[i]);
        PII start;
        for (int i = 0; i < n; i ++ )
            for (int j = 0; j < m; j ++ )
                if (g[i][j] == 'S') start = make_pair(i, j);
        
        int distance = bfs(start);
        if (distance == -1) puts("oop!");
        else cout << distance << endl;
    }
    return 0;
}

四、其它题解

AcWing 1101. 献给阿尔吉侬的花束 1

AcWing 1101. 献给阿尔吉侬的花束 2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值