题目链接:
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=98233#problem/H
题目大意:
模拟一个人走迷宫,遇到怪兽要和他决斗,决斗时间为那个格子的数字。输出(0,0)->(n-1,m-1)的最短路且show the way。
分析:
题不难,不过写的时候太粗心了,第一次dfs没过,之后用bfs+记忆化搜索,有个细节写的时候没注意,改了好久才反应过来。唯一一个比较麻烦的点就是打印路径,用一个结构体数组dir[4] = { { 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 } };
记录方向,用int mark[y][x]记录上一个位置(y1,x1)到本次位置(y,x)的方向下标i。本次位置=上一个位置+dir[i],那么上一个位置=本次位置-dir[i],由最后一个位置(N-1,M-1)递归往回找,直到位置(0,0)停止。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<stdlib.h>
#include<queue>
using namespace std;
#define MAX 100000
struct node
{
int x;//对应列
int y;//对应行
};
struct node dir[4] = { { 0, -1 }, { -1, 0 }, { 1, 0 }, { 0, 1 } };
char map[105][105];
int vis[105][105];
int mark[105][105];//路径
int N, M;
bool flag;
bool judge(int x,int y)
{
if (x >= 0 && x < M && y >= 0 && y < N && map[y][x] != 'X')
{
return true;
}
return false;
}
void BFS()
{
struct node p;
p.x = 0;
p.y = 0;
vis[0][0] = 0;
queue<node> q;
q.push(p);
while (!q.empty())
{
p = q.front();
q.pop();
if (p.y == N - 1 && p.x == M - 1)
{
flag = true;
//return;
}
for (int i = 0; i < 4; i++)
{
struct node p1 = p;
p1.y += dir[i].y;
p1.x += dir[i].x;
if (judge(p1.x, p1.y))
{
int curTime = 0;
if (map[p1.y][p1.x]>='1' && map[p1.y][p1.x]<='9')
{
curTime += (int)(map[p1.y][p1.x]-'0'+1);
}
else
{
curTime++;
}
if (vis[p1.y][p1.x] > curTime + vis[p.y][p.x])
{
vis[p1.y][p1.x] = curTime + vis[p.y][p.x];
q.push(p1);
mark[p1.y][p1.x]=i;
}
}
}
}
}
int ans;
void showPath(int y,int x)
{
if (y == 0 && x == 0)
{
return;
}
int y1 = y - dir[mark[y][x]].y;
int x1 = x - dir[mark[y][x]].x;
showPath(y1,x1);
printf("%ds:(%d,%d)->(%d,%d)\n",ans++,y1,x1,y,x);
if (map[y][x] >= '1' && map[y][x] <= '9')
{
int time = map[y][x] - '0';
while (time--)
{
printf("%ds:FIGHT AT (%d,%d)\n", ans++, y, x);
}
}
}
int main()
{
while (scanf("%d%d", &N, &M) != EOF)
{
flag = false;
memset(mark,0,sizeof(mark));
memset(map,0,sizeof(map));
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cin >> map[i][j];
vis[i][j] = MAX;
}
}
BFS();
if (!flag)
{
printf("God please help our poor hero.\n");
}
else
{
int min = vis[N - 1][M - 1];
ans = 1;
printf("It takes %d seconds to reach the target position, let me show you the way.\n", min);
showPath(N-1,M-1);
}
printf("FINISH\n");
}
return 0;
}