AtCoder题解 —— AtCoder Beginner Contest 184 —— E - Third Avenue - BFS
题目相关
题目链接
AtCoder Beginner Contest 184 E 题,https://atcoder.jp/contests/abc184/tasks/abc184_e。
Problem Statement
There is a town represented as a two-dimensional grid with H horizontal rows and W vertical columns.
A character ai,j describes the square at the i-th row from the top and j-th column from the left. Here, ai,j is one of the following: S
, G
, .
, #
, a
, ..., and z
.
#
represents a square that cannot be entered, and a
, ..., z
represent squares with teleporters.
Takahashi is initially at the square represented as S
. In each second, he will make one of the following moves:
- Go to a non-
#
square that is horizontally or vertically adjacent to his current position. - Choose a square with the same character as that of his current position, and teleport to that square. He can only use this move when he is at a square represented as
a
, ..., orz
.
Find the shortest time Takahashi needs to reach the square represented as G
from the one represented as S
.
If the destination is unreachable, report -1
instead.
Input
Input is given from Standard Input in the following format:
H W
a1,1 ... a1,w
.
.
.
ah,1 ... ah,w
Output
Print the shortest time Takahashi needs to reach the square represented as G
from the one represented as S
.
If the destination is unreachable from the initial position, print -1
instead.
Samples1
Sample Input 1
2 5
S.b.b
a.a.G
Sample Output 1
4
Explaination
Let (i,j) denote the square at the i-th row from the top and j-th column from the left.
Initially, Takahashi is at (1,1). One way to reach (2,5) in four seconds is:
- go from (1,1) to (2,1);
- teleport from (2,1) to (2,3), which is also an
a
square; - go from (2,3) to (2,4);
- go from (2,4) to (2,5).
Samples2
Sample Input 2
11 11
S##...#c...
...#d.#.#..
..........#
.#....#...#
#.....bc...
#.##......#
.......c..#
..#........
a..........
d..#...a...
.#........G
Sample Output 2
14
Samples3
Sample Input 3
11 11
.#.#.e#a...
.b..##..#..
#....#.#..#
.#dd..#..#.
....#...#e.
c#.#a....#.
.....#..#.e
.#....#b.#.
.#...#..#..
......#c#G.
#..S...#...
Sample Output 3
-1
Constraints
- 1≤H,W≤2000
- ai,j is
S
,G
,.
,#
, or a lowercase English letter. There is exactly one square represented asS
and one square represented asG
.
题解报告
题目翻译
请找出高桥从 S 到 G 的最短路径,如果不存在,输出 -1。
题目分析
看完题目描述,走迷宫并且是找出最短路线,那么必然使用 BFS。本题和 BFS 模板相比,多了一个传送点,如何解决传送点问题。根据题目意思,我们一共有四种走法,即上、右、下、左。
1、在某个点判断下一个位置的时候,不考虑下一个点是否是传送点,和原有的 BFS 一样进行移动。
2、所有下一个可能位置计算完成后,判断这个点是否是传送点。如果是传送点,遍历修改传送点的代价 cost。修改结束,清空所有传送点。
样例数据 1 分析
初始状态
1 | 2 | 3 | 4 | 5 | |
1 | 0 | INT_MAX | INT_MAX | INT_MAX | INT_MAX |
2 | INT_MAX | INT_MAX | INT_MAX | INT_MAX | INT_MAX |
第一轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (1,1),并删除该数据,我们从 (1,1) 开始遍历。目前的代价为 0,从这里出发到下一个位置的代价将为 2。
(1,1) 向上
(1,1) 向右
(1,1) 向下
(1,1) 向左
判断 (1,1) 是不是传送点
第一轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | INT_MAX | INT_MAX | INT_MAX |
2 | 1 | INT_MAX | INT_MAX | INT_MAX | INT_MAX |
第二轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (2,1),并删除该数据,我们从 (2,1) 开始遍历。目前的代价为 1,从这里出发到下一个位置的代价将为 2。
(2,1) 向上
(2,1) 向右
(2,1) 向下
(2,1) 向左
新位置为 (1,1),是合法位置,而且不是 #,可以走。当前 cost[1][1]=0,而我们移动的代价是 2,所以忽略。
判断 (2,1) 是不是传送点
第二轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | INT_MAX | INT_MAX | INT_MAX |
2 | 1 | 2 | 2 | INT_MAX | INT_MAX |
第三轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (1,2),并删除该数据,我们从 (1,2) 开始遍历。目前已经的代价是 1,从这里出发到下一个位置的代价将为 2。
(1,2) 向上
新位置为 (1,1),是合法位置,而且不是 #,可以走。当前 cost[1][2]=0,而我们移动的代价是 2,就是从 (1,2) 移动到 (1,1) 的代价是 2。所以忽略。
(1,2) 向右
(1,2) 向下
(1,2) 向左
判断 (1,2) 是不是传送点
第三轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | INT_MAX | INT_MAX |
2 | 1 | 2 | 2 | INT_MAX | INT_MAX |
第四轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (2,2),并删除该数据,我们从 (2,2) 开始遍历。目前已经的代价是 2,从这里出发到下一个位置的代价将为 3。
(2,2) 向上
新位置为 (2,1),是合法位置,而且不是 #,可以走。当前 cost[2][1]=1,而我们移动的代价是 3。所以忽略。
(2,2) 向右
(2,2) 向下
新位置为 (2,3),是合法位置,而且不是 #,可以走。当前 cost[2][3]=2,而我们移动的代价是 3。所以忽略。
(2,2) 向左
新位置为 (1,2),是合法位置,而且不是 #,可以走。当前 cost[1][2]=1,而我们移动的代价是 3。所以忽略。
判断 (2,2) 是不是传送点
第四轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | INT_MAX | INT_MAX |
2 | 1 | 2 | 2 | INT_MAX | INT_MAX |
第五轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (2,3),并删除该数据,我们从 (2,3) 开始遍历。目前已经的代价是 2,从这里出发到下一个位置的代价将为 3。
(2,3) 向上
新位置为 (2,2),是合法位置,而且不是 #,可以走。当前 cost[2][2]=2,而我们移动的代价是 3。所以忽略。
(2,3) 向右
(2,3) 向下
(2,3) 向左
新位置为 (1,3),是合法位置,而且不是 #,可以走。当前 cost[1][3]=2,而我们移动的代价是 3。所以忽略。
判断 (2,3) 是不是传送点
当前位置是传送点。但是这个传送点已经处理了,上面我们处理的时候,将这个队列清空。
第五轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | INT_MAX | INT_MAX |
2 | 1 | 2 | 2 | 3 | INT_MAX |
第六轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (1,3),并删除该数据,我们从 (1,3) 开始遍历。目前已经的代价是 2,从这里出发到下一个位置的代价将为 3。
(1,3) 向上
新位置为 (1,2),是合法位置,而且不是 #,可以走。当前 cost[1][2]=1,而我们移动的代价是 3。所以忽略。
(1,3) 向右
新位置为 (2,3),是合法位置,而且不是 #,可以走。当前 cost[2][3]=2,而我们移动的代价是 3。所以忽略。
(1,3) 向下
(1,3) 向左
判断 (1,3) 是不是传送点
第六轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | 3 | 3 |
2 | 1 | 2 | 2 | 3 | INT_MAX |
第七轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (2,4),并删除该数据,我们从 (2,4) 开始遍历。目前已经的代价是 3,从这里出发到下一个位置的代价将为 4。
(2,4) 向上
新位置为 (2,3),是合法位置,而且不是 #,可以走。当前 cost[2][3]=2,而我们移动的代价是 4。所以忽略。
(2,4) 向右
(2,4) 向下
(2,4) 向左
新位置为 (1,4),是合法位置,而且不是 #,可以走。当前 cost[1][4]=3,而我们移动的代价是 4。所以忽略。
判断 (2,4) 是不是传送点
第七轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | 3 | 3 |
2 | 1 | 2 | 2 | 3 | 4 |
第八轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (1,4),并删除该数据,我们从 (1,4) 开始遍历。目前已经的代价是 3,从这里出发到下一个位置的代价将为 4。
(1,4) 向上
新位置为 (1,3),是合法位置,而且不是 #,可以走。当前 cost[1][3]=2,而我们移动的代价是 4。所以忽略。
(1,4) 向右
新位置为 (2,4),是合法位置,而且不是 #,可以走。当前 cost[2][4]=3,而我们移动的代价是 4。所以忽略。
(1,4) 向下
新位置为 (1,5),是合法位置,而且不是 #,可以走。当前 cost[1][5]=4,而我们移动的代价是 4。所以忽略。
(1,4) 向左
判断 (1,4) 是不是传送点
第八轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | 3 | 3 |
2 | 1 | 2 | 2 | 3 | 4 |
第九轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (1,5),并删除该数据,我们从 (1,5) 开始遍历。目前已经的代价是 3,从这里出发到下一个位置的代价将为 4。
(1,5) 向上
新位置为 (1,4),是合法位置,而且不是 #,可以走。当前 cost[1][4]=3,而我们移动的代价是 4。所以忽略。
(1,5) 向右
新位置为 (2,5),是合法位置,而且不是 #,可以走。当前 cost[2][5]=4,而我们移动的代价是 4。所以忽略。
(1,5) 向下
(1,5) 向左
判断 (1,5) 是不是传送点
第九轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | 3 | 3 |
2 | 1 | 2 | 2 | 3 | 4 |
第十轮 BFS 遍历队列
BFS 遍历队列不为空,获取队首位置,得到 (2,5),并删除该数据,我们从 (2,5) 开始遍历。目前已经的代价是 4,从这里出发到下一个位置的代价将为 5。
(2,5) 向上
新位置为 (2,4),是合法位置,而且不是 #,可以走。当前 cost[2][4]=3,而我们移动的代价是 5。所以忽略。
(2,5) 向右
(2,5) 向下
(2,5) 向左
新位置为 (1,5),是合法位置,而且不是 #,可以走。当前 cost[1][5]=3,而我们移动的代价是 5。所以忽略。
判断 (2,5) 是不是传送点
第十轮 BFS 遍历结束
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 1 | 2 | 3 | 3 |
2 | 1 | 2 | 2 | 3 | 4 |
到这里为止,BFS 队列为空,说明我们遍历了迷宫的所有点。遍历完成。
注意:只要 BFS 第一次走到终点,BFS 就可以停止了,因为 BFS 可以保证第一次就是最短路径。
AC 参考代码
//https://atcoder.jp/contests/abc184/tasks/abc184_e
//E - Third Avenue
#include <bits/stdc++.h>using namespace std;//如果提交到OJ,不要定义 __LOCAL
//#define __LOCALconst int MAXH=2e3+4;
const int MAXW=2e3+4;
char maze[MAXH][MAXW];
int cost[MAXH][MAXW];int h,w;
pair<int, int> qd;
pair<int, int> zd;
vector<pair<int, int>> tele[26];const int dx[]={0, 1, 0, -1};
const int dy[]={-1, 0, 1, 0};int bfs() {queue<pair<int, int>> q;q.push(qd);cost[qd.first][qd.second]=0;while (true!=q.empty()) {pair<int, int> cur = q.front();q.pop();int nc=cost[cur.first][cur.second]+1;//下一个位置的代价//新位置for (int i=0; i<4; i++) {int nx = cur.first+dx[i];int ny = cur.second+dy[i];//合法性判断if (nx<1||nx>h||ny<1||ny>w||'#'==maze[nx][ny]) {continue;}//路径判断if (nc<cost[nx][ny]) {cost[nx][ny]=nc;q.emplace(nx, ny);//判断是不是终点if (nx==zd.first && ny==zd.second) {return nc;}}}//如果是传送点if (maze[cur.first][cur.second]>='a' && maze[cur.first][cur.second]<='z') {//将所有的vector<pair<int, int>> &t=tele[maze[cur.first][cur.second]-'a'];vector<pair<int, int>>::iterator it;for (it=t.begin(); it!=t.end(); it++) {if (nc<cost[it->first][it->second]) {cost[it->first][it->second]=nc;q.emplace(it->first, it->second);}}t.clear();}}return -1;
}int main() {
#ifndef __LOCAL//这部分代码需要提交到OJ,本地调试不使用ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#endifcin>>h>>w;for (int i=1; i<=h; i++) {for (int j=1; j<=w; j++) {cost[i][j]=INT_MAX;cin>>maze[i][j];if ('S'==maze[i][j]) {//起点qd.first=i;qd.second=j;cost[i][j]=0;} else if ('G'==maze[i][j]) {zd.first=i;zd.second=j;} else if (maze[i][j]>='a' && maze[i][j]<='z') {tele[maze[i][j]-'a'].emplace_back(i, j);}}}//开始BFScout<<bfs()<<"\n";#ifdef __LOCAL//这部分代码不需要提交到OJ,本地调试使用system("pause");
#endifreturn 0;
}
时间复杂度
空间复杂度
AtCoder题解 —— AtCoder Beginner Contest 184 —— E - Third Avenue - BFS相关推荐
- AtCoder题解 —— AtCoder Beginner Contest 182 —— D - Wandering
题目相关 题目链接 AtCoder Beginner Contest 182 D 题,https://atcoder.jp/contests/abc182/tasks/abc182_d. Proble ...
- AtCoder题解 —— AtCoder Beginner Contest 187 —— B - Gentle Pairs —— 暴力
题目相关 题目链接 AtCoder Beginner Contest 187 B 题,https://atcoder.jp/contests/abc187/tasks/abc187_b. Proble ...
- AtCoder题解—— AtCoder Beginner Contest 181 —— B - Trapezoid Sum
题目相关 题目链接 AtCoder Beginner Contest 181 B 题,https://atcoder.jp/contests/abc181/tasks/abc181_b. Proble ...
- AtCoder题解——AtCoder Grand Contest 048——A - atcoder < S
题目相关 题目链接 AtCoder Grand Contest 048 A 题,https://atcoder.jp/contests/agc048/tasks/agc048_a. Problem S ...
- AtCoder题解 —— AtCoder Grand Contest 050 —— B - Three Coins —— 动态规划
题目相关 题目链接 AtCoder Grand Contest 050 B 题,https://atcoder.jp/contests/agc050/tasks/agc050_b. Problem S ...
- AtCoder题解——AtCoder Regular Contest 107——B - Quadruple
题目相关 题目链接 AtCoder Regular Contest 107 B 题,https://atcoder.jp/contests/arc107/tasks/arc107_b. Problem ...
- Atcoder题解与视频集
开启Atcoder之路 开启Atcoder之路_sortmin的博客-CSDN博客_atcoder怎么用 atcoder心得 atcoder心得_404REN的博客-CSDN博客_atcoder怎么用 ...
- AtCoder题解——Beginner Contest 170——F - Pond Skater
题目相关 题目链接 AtCoder Beginner Contest 170 F题,https://atcoder.jp/contests/abc170/tasks/abc170_f. Problem ...
- AtCoder题解——Beginner Contest 167——C - Skill Up
题目相关 题目链接 AtCoder Beginner Contest 167 C题,https://atcoder.jp/contests/abc167/tasks/abc167_c. Problem ...
- AtCoder Beginner Contest 246 A~E 题解 Bishop 2
AtCoder Beginner Contest 246 A~E 题解 A Four Points 题意 给你矩形的三个顶点,输出剩下那个 思路 把横坐标和纵坐标分开,必会存在两个相同的数,横纵坐标就 ...
最新文章
- 托管代码与非托管代码
- mysql 编译_mysql 5.7 编译——VS2017
- 【算法】快速选择算法 ( 数组中找第 K 大元素 )
- JSP+Servlet + JDBC 实现简单的登录验证模块
- SDN控制器OpenDaylight简介—VeCloud
- Java String关于replaceall函数转义字符的一个小贴士
- cmake (0)简介
- NOSQL 之 cassadra 安装与集群配置
- jzoj5702-[gdoi2018day2]滑稽子图【树形dp,二项式定理】
- Eclipse里的快捷键
- relativelayout中按键不能点_CNC | M80/M800系列系统常见按键和外部存储器故障
- 程序员职场:3 大原则让你的编程之路越走越顺,新手来了解一下
- leetcode 95 python
- 市面上有哪几种门_实木门、原木门、模压门,各有门道不怕坑!
- mysql自定义函数to_date_mysql 之 str_to_date ()函数 和date_format()函数
- python模块之subprocess
- C语言求解圆周率近似值
- Unity - Timeline 之 Timeline Preview and Timeline Selector(Timeline预览与Timeline选择器)
- win10无法msi文件的解决方法
- [转]伽利略卫星导航系统2019年7月14日起的宕机事件