http://acm.hdu.edu.cn/showproblem.php?pid=1072
题意:
一个地图,有一个炸弹,6秒内爆炸,地图上0是表示墙,1表示路,4可以重置炸弹,3是出口,2是起始位置,问能不能在炸弹爆炸前走出去,炸弹时间为0是到达4和3都会死
思路:
一个BFS广搜,对于地图上的每个点都记录一个时间,代表到达这个点的时候炸弹的倒计时,因为每个点都是是可以反复走的,而4这个点如果反复走的话,并不会节省时间,所以每次走的时候,跟这个位置的时间比较,只有当前时间 - 1大于这个点的原本时间,那么这条路是可以重新走一遍的,否则就不走,
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <string.h>
#include <queue>
#include <stack>
#include <deque>
#include <stdlib.h>
#include <bitset>
using namespace std;
#define ll long long
#define ull unsigned long long
const int INF = 0x3f3f;
struct XY{
int x, y, minu, cnt;
XY() {}
XY(int _x, int _y, int _minu, int _cnt) {
x = _x; y = _y; minu = _minu; cnt = _cnt;
}
};
int xx, yy;
queue<XY> que;
int mapp[10][10];
int n, m;
int nx[4] = {0, 0, 1, -1}, ny[4] = {-1, 1, 0, 0};
int dp[10][10];
int ans = INF;
int bfs() {
XY t;
while(!que.empty()) {
t = que.front();
que.pop();
if(t.minu == 1)//如果当前点为1,那么怎么走都是死
continue;
for (int i = 0; i < 4; i ++) {
int tx = t.x + nx[i], ty = t.y + ny[i];
if(tx <= n && tx >= 1 && ty <= m && ty >= 1) {
if(mapp[tx][ty] == 1) {
if(dp[tx][ty] < t.minu - 1) {//如果当前时间-1>原本时间,那么可以走
que.push(XY(tx, ty, t.minu - 1, t.cnt + 1));
dp[tx][ty] = t.minu - 1;
}
}
else if(mapp[tx][ty] == 4) {
if(dp[tx][ty] < 6) {//如果以前没有到过这个4点,
que.push(XY(tx, ty, 6, t.cnt + 1));
dp[tx][ty] = 6;//到达了就把dp[tx][ty] = 6
}
}
else if(mapp[tx][ty] == 3)
return t.cnt + 1;
}
}
}
return -1;
}
int main(int argc, const char * argv[]) {
int T;
scanf("%d", &T);
while(T --) {
scanf("%d %d", &n, &m);
while(!que.empty())
que.pop();
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++) {
scanf("%d", &mapp[i][j]);
if (mapp[i][j] == 2)
que.push(XY(i, j, 6, 0));
}
printf("%d\n", bfs());
}
return 0;
}