Hdu 1180 诡异的电梯(优先队列搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1180
测试数据:
3 4
T...
*-*S
*.|.
输出:
4
这道题花了好久才过,怎么交怎么错…直到看到了hdu讨论板的一组数据,调试了才发现问题,用优先队列可能会导致到一个点的距离变的更远了,这个时候我想,过楼梯之后的那个点不用vis标记是不是就可以了,果然还是不行。
最后想干脆不要标记数组了,改为类记忆化思路,只有更短的路可以进队列,然后ac了。代码如下:
#include<bits/stdc++.h>
using namespace std;
int n, m, sx, sy, ex, ey;
#define inf 0x3f3f3f
char maze[25][25];
int v[25][25];//标记数组,记录到x,y的当前最短距离
int to[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
inline bool check(int i, int j) {
if (i >= 1 && i <= n && j >= 1 && j <= m && maze[i][j] != '*')return true;
return false;
}
struct node {
int x, y, step;
friend bool operator<(const node &a, const node &b) {
return a.step > b.step;
}
} now;
inline void bfs() {
priority_queue<node> q;
q.push(node{sx, sy, 0});
while (!q.empty()) {
now = q.top();
q.pop();
if (now.x == ex && now.y == ey) {//用优先队列来保证最快
printf("%d\n", now.step);
return;
}
for (int i = 0; i < 4; i++) {
int xx = now.x + to[i][0];
int yy = now.y + to[i][1];
if (check(xx, yy)) {
if (maze[xx][yy] == '.' || maze[xx][yy] == 'T') {//.和T直接过
if (now.step + 1 < v[xx][yy]) {//如果没有走过比当前的短的距离才加入队列
q.push(node{xx, yy, now.step + 1});
v[xx][yy] = now.step + 1;
}
} else {//遇到楼梯了
char c = maze[xx][yy];
xx += to[i][0];
yy += to[i][1];
if (check(xx, yy)) {//能过楼梯
if (c == '|') {
if (now.step & 1) {//c=='-'
if (i == 0 || i == 1) {//上下走
if (now.step + 2 < v[xx][yy]) {//同上
q.push(node{xx, yy, now.step + 2});//得等一秒
v[xx][yy] = now.step + 2;
}
} else {
if (now.step + 1 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 1});//直接过
v[xx][yy] = now.step + 1;
}
}
} else {//c=='|'
if (i == 0 || i == 1) {//上下走
if (now.step + 1 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 1});//可以直接过
v[xx][yy] = now.step + 1;
}
} else {
if (now.step + 2 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 2});
v[xx][yy] = now.step + 2;
}
}
}
} else if (c == '-') {
if (now.step & 1) {//c=='|'
if (i == 0 || i == 1) {
if (now.step + 1 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 1});
v[xx][yy] = now.step + 1;
}
} else {
if (now.step + 2 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 2});
v[xx][yy] = now.step + 2;
}
}
} else {//c=='|'
if (i == 0 || i == 1) {
if (now.step + 2 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 2});
v[xx][yy] = now.step + 2;
}
} else {
if (now.step + 1 < v[xx][yy]) {
q.push(node{xx, yy, now.step + 1});
v[xx][yy] = now.step + 1;
}
}
}
}
}
}
}
}
}
}
int main() {
while (scanf("%d %d", &n, &m) != EOF) {
for (int i = 1; i <= n; i++) {
scanf("%s", maze[i] + 1);
for (int j = 1; j <= m; j++) {
if (maze[i][j] == 'S') {
sx = i;
sy = j;
}
if (maze[i][j] == 'T') {
ex = i;
ey = j;
}
v[i][j] = inf;//把距离初始化为最大值
}
}
bfs();
}
return 0;
}