题目链接
简单说下题意,就是给一个迷宫.一开始有6滴血,走一步掉一滴.路上有补血包,问能不能在血量>=1的情况下到达终点.
这题其实就是HDU上面的1072.个人做题习惯搜索题最短路一般用BFS,可行问题一般用DFS.看了下洛谷上面的题解用DFS写这题的.给组数据大家可以测试一下自己的DFS写的够不够好(用了某个题解的算法这个数据是会超时的.)
9 9
2 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 4
4 4 4 4 4 4 4 4 3
这题的BFS解法其实并不难理解.我们vis数组可以考虑多开一维记录到当前位置剩余的血量值.因为这题的补血包是可以无限用的(如果是只能用一次的话可能DFS会更好吧.)所以在某个位置如果血量和之前某个状态一样的情况下就可以扔掉这个状态的了.其他也没什么要注意的了.
附上代码
#define LL long long
#define pb push_back
#include <iostream>
#include <algorithm>
#include <string.h>
#include <cmath>
#include <string>
#include <cstdio>
#include <set>
#include <vector>
#include <sstream>
#include <queue>
using namespace std;
struct Node {
int r, c, cost, l;
};
const int N = 10;
int maze[N][N];
bool vis[N][N][10];
int dr[4] = { 1,-1,0,0 };
int dc[4] = { 0,0,1,-1 };
int n, m, t;
bool inside(int r, int c) {
if (r >= 1 && r <= n && c >= 1 && c <= m) return true;
return false;
}
int r1, r2, c1, c2, ans = -1;
bool bfs() {
Node st = { r1,c1,6,0 };
queue<Node> q;
q.push(st);
vis[r1][c1][6] = 1;
while (!q.empty()) {
Node cur = q.front();
q.pop();
if (cur.cost == 0) continue;
if (cur.r == r2 && cur.c == c2) {
ans = cur.l;
return true;
}
for (int i = 0; i < 4; ++i) {
int nr = cur.r + dr[i], nc = cur.c + dc[i];
if (!inside(nr, nc)) continue;
if (!maze[nr][nc]) continue;
if (maze[nr][nc] == 4) {
if (cur.cost == 1) continue;
if (vis[nr][nc][6]) continue;
vis[nr][nc][6] = 1;
Node nn = { nr,nc,6,cur.l + 1 };
q.push(nn);
}
else {
if (vis[nr][nc][cur.cost - 1]) continue;
vis[nr][nc][cur.cost - 1] = 1;
Node nn = { nr,nc,cur.cost - 1,cur.l + 1 };
q.push(nn);
}
}
}
return false;
}
int main() {
ios::sync_with_stdio(false);
int t;
memset(vis, 0, sizeof(vis));
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
cin >> maze[i][j];
if (maze[i][j] == 2) r1 = i, c1 = j;
if (maze[i][j] == 3) r2 = i, c2 = j;
}
}
if (bfs()) cout << ans << endl;
else cout << -1 << endl;
return 0;
}