题目链接:HDU 1242 Rescue营救
Angel被关在一个监狱中,监狱可有N*M的矩阵表示,每个方格中可能有墙壁(#)、道路(.)、警卫(x)、Angel(a)和Angel的朋友(r)。Angel的朋友想到达Angel处,要么走道路,需要1的时间,要么走到警卫的格子,还需要多1的时间杀死警卫才能通行。现在需要求到达Angel处的最短时间。
分析:
求最短时间一般都用BFS搜索,但是这道题条件较多,需要酌情考虑。并不是步数最少就最好,因为杀死警卫还需要额外的时间。可以新建一个结构体point,表示当前位置和已经使用的时间。再申请一个数组mintime[][],表示走到某一格的最短时间。将可行的当前位置压入队列并持续更新mintime数组。找到Angel所在位置的mintime。
代码:
#include
#include
#include
#include
using namespace std;
#define INF 0xffffff
char mp[202][202];
int n, m, mintime[202][202];
int dir[4][2] = {{-1, 0},{0, 1},{1, 0},{0, -1}};
struct point
{
int x, y, time;
};
void bfs(point s)
{
queue q;
q.push(s);
while(!q.empty())
{
point cp = q.front();
q.pop();
for(int i = 0; i < 4; i++)
{
int tx = cp.x + dir[i][0];
int ty = cp.y + dir[i][1];
if(tx >= 1 && tx <= n && ty >= 1 && ty <= m && mp[tx][ty] != '#')
{
point t;
t.x = tx;
t.y = ty;
t.time = cp.time+1;
if(mp[tx][ty] == 'x')
t.time++;
if(t.time < mintime[tx][ty])
{
mintime[tx][ty] = t.time;
q.push(t);
}
}
}
}
}
int main()
{
char c;
int ax, ay;
point st;
while(~scanf("%d%d", &n, &m))
{
scanf("%c", &c);
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
scanf("%c", &mp[i][j]);
mintime[i][j] = INF;
if(mp[i][j] == 'a')
{
ax = i;
ay = j;
}
else if(mp[i][j] == 'r')
{
st.x = i;
st.y = j;
st.time = 0;
}
}
scanf("%c", &c);
}
mintime[st.x][st.y] = 0;
bfs(st);
if(mintime[ax][ay] < INF)
printf("%d\n", mintime[ax][ay]);
else
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
return 0;
}