题目链接
题目大意
给出一个n*m的矩阵,里面包含了起点位置和终点位置和所有传送门的位置,现在有一头牛在起点,他可以往上下左右四个方向行动,每行动一格将花费一个单位的时间,使用传送门不需要时间(传送门用大写字母A~W表示),传送门以一对的形式存在。最后就是输出从起点到终点所花费的最小时间。
解题思路
首先明确,这是一道广搜的题目,因为只用找一条从起点到终点的用时最短路。那么我们来考虑一下,本道题和普通的广搜迷宫有什么不同。显而易见,唯一的不同就是多了一堆双向传送的传送门,所以我们只要在输入的时候记录一下每一对传送门的位置,然后在广搜遇到的时候再把下一个点修改为对应传送门的坐标就好了,其余的东西和广搜模板都是一样的。
上代码!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define pii pair<int, int>
#define mp(a, b) make_pair(a, b)
#define piii pair<pii, int>
#define min(a, b) (a < b ? a : b)
#define max(a, b) (a > b ? a : b)
#define uf(a, b, i) for (register int i = (a); i <= (b); ++i)
#define df(a, b, i) for (register int i = (a); i >= (b); --i)
using namespace std
;
inline ll
read() {
ll x
= 0, f
= 1;
char ch
= getchar();
while(ch
< '0' || ch
> '9') {
if(ch
== '-') f
= -1;
ch
= getchar();
}
while(ch
>= '0' && ch
<= '9') {
x
= x
* 10 + ch
- '0';
ch
= getchar();
}
return x
* f
;
}
const int N
= 303;
int n
, m
, sx
, sy
, ex
, ey
;
char s
[N
][N
];
bool vis
[N
][N
];
int cnt
[N
][N
];
int a
[27][2][2];
int cx
[] = {0, 0, 1, -1};
int cy
[] = {1, -1, 0, 0};
queue
<pii
> q
;
pii p
;
inline bool right(int x
, int y
) {
return (x
> 0 && x
<= n
&& y
> 0 && y
<= m
&& !vis
[x
][y
] && s
[x
][y
] != '#');
}
void bfs(int x
, int y
) {
vis
[x
][y
] = 1;
q
.push(mp(x
, y
));
while (!q
.empty()) {
p
= q
.front();
uf(0, 3, i
) {
int xx
= p
.first
+ cx
[i
];
int yy
= p
.second
+ cy
[i
];
if (right(xx
, yy
)) {
if (s
[xx
][yy
] >= 'A' && s
[xx
][yy
] <= 'Z') {
int posx
= xx
, posy
= yy
;
if (posx
== a
[s
[xx
][yy
]-'A'][0][0] && posy
== a
[s
[xx
][yy
]-'A'][0][1])
posx
= a
[s
[xx
][yy
]-'A'][1][0], posy
= a
[s
[xx
][yy
]-'A'][1][1];
else posx
= a
[s
[xx
][yy
]-'A'][0][0], posy
= a
[s
[xx
][yy
]-'A'][0][1];
if (cnt
[posx
][posy
] == 0) cnt
[posx
][posy
] = cnt
[p
.first
][p
.second
] + 1;
else cnt
[posx
][posy
] = min(cnt
[posx
][posy
], cnt
[p
.first
][p
.second
] + 1);
q
.push(mp(posx
, posy
));
} else {
vis
[xx
][yy
] = 1;
cnt
[xx
][yy
] = cnt
[p
.first
][p
.second
] + 1;
if (xx
== ex
&& yy
== ey
) {
printf("%d\n", cnt
[xx
][yy
]);
while (q
.size()) q
.pop();
return ;
}
q
.push(mp(xx
, yy
));
}
}
}
q
.pop();
}
}
int main() {
n
= read(); m
= read();
uf(1, n
, i
) {
scanf("%s", s
[i
]+1);
uf(1, m
, j
) {
if (s
[i
][j
] == '@') sx
= i
, sy
= j
;
else if (s
[i
][j
] == '=') ex
= i
, ey
= j
;
else if (s
[i
][j
] >= 'A' && s
[i
][j
] <= 'Z') {
if (a
[s
[i
][j
]-'A'][0][0] == 0) a
[s
[i
][j
]-'A'][0][0] = i
, a
[s
[i
][j
]-'A'][0][1] = j
;
else a
[s
[i
][j
]-'A'][1][0] = i
, a
[s
[i
][j
]-'A'][1][1] = j
;
}
}
}
bfs(sx
, sy
);
return 0;
}