在HDOJ上提交通过以后,再在zoj上提交,结果得到了无数个WA,后来发现有一种情况我并没有考虑到
有几个关键的地方需要注意:
1. Angel的朋友不只有一个,可能有多个
2. guard的存在可能会破坏广度优先树
解决办法:
BFS的做法:必须要保存guard与可行点‘.’的插入同步,因为guard的costTime不同,应该先不改变其坐标,costTime增加一以后,设为已被访问,‘x’变为‘.’或者‘#’,重新入队,此时,guard已被插入到队列的尾部,这样一来,guard与‘.’就可以同步了
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
char maze[210][210];
int vis[210][210];
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
int nNum, mNum, i, j, sx, sy;
struct Node
{
int x;
int y;
int step;
};
int IsInBound(int x, int y)
{
if (x<0 || y<0 || x>=nNum || y>=mNum)
{
return 0;
}
return 1;
}/* IsInBound */
void BFS()
{
int k;
int front = -1;
int rear = -1;
int isSolve = 0;
struct Node dir, cur;
struct Node q[40010] = {0};
cur.x = sx;
cur.y = sy;
cur.step = 0;
q[++rear] = cur;
vis[sx][sy] = 1;
while (front != rear)
{
cur = q[++front];
if (maze[cur.x][cur.y] == 'r')
{
isSolve = 1;
break;
}
/**
* 因为没有考虑这个,导致WA了无数次,
* guards的存在可能会破坏广度优先树,因为是
* 它的costTime与可行路‘.’的costTime不同步
*
* 先不改变当前的坐标,干掉guard以后,将x变为可行
* 路径‘.’,在压入队列中,这样可以保持同步
***/
if (maze[cur.x][cur.y] == 'x')
{
++cur.step;
vis[cur.x][cur.y] = 1;
maze[cur.x][cur.y] = '.';
q[++rear] = cur;
}
else
{
for (k=0; k<4; ++k)
{
dir.x = cur.x + dx[k];
dir.y = cur.y + dy[k];
dir.step = cur.step + 1;
if (!vis[dir.x][dir.y] && maze[dir.x][dir.y]!='#'
&& IsInBound(dir.x, dir.y))
{
vis[dir.x][dir.y] = 1;
q[++rear] = dir;
}
}/* End of For */
}
}/* End of While */
if (isSolve)
{
printf("%d\n", cur.step);
}
else
{
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
}/* BFS */
int main()
{
while (2 == scanf("%d %d", &nNum, &mNum))
{
getchar();
memset(maze, 0, sizeof(maze));
memset(vis, 0, sizeof(vis));
for (i=0; i<nNum; ++i)
{
scanf("%s", maze[i]);
}/* End of For */
/*
* 因为Angel不只有一个Friend
* 可能有多个friends
*/
for (i=0; i<nNum; ++i)
{
for (j=0; j<mNum; ++j)
{
if (maze[i][j] == 'a')
{ /* 找出Angel的位置,从Angel的位置开始探索 */
sx = i, sy = j;
}
}
}/* End of For */
BFS();
}/* End of While */
return 0;
}
第二种方法是:利用优先队列,按可行点时间的大少,costTime少的优先,即最少值优先,如此一来,guard的访问点就会插入到队列的队尾了
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <memory.h>
using namespace std;
char maze[210][210];
int vis[210][210];
int i, j, nNum, mNum, sx, sy;
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};
struct Node
{
int x, y, step;
bool operator < (const Node &a) const
{
return step > a.step;
}
};
int IsInBound(int x, int y)
{
if (x<0 || y<0 || x>=nNum || y>=mNum)
{
return 0;
}
return 1;
}/* IsInBound */
void BFS()
{
int k, isSolve = 0;
Node cur, next;
priority_queue<Node> q;
cur.x = sx;
cur.y = sy;
cur.step = 0;
q.push(cur);
vis[sx][sy] = 1;
while (!q.empty())
{
cur = q.top();
q.pop();
if (maze[cur.x][cur.y] == 'r')
{
isSolve = 1;
break;
}
for (k=0; k<4; ++k)
{
next.x = cur.x + dx[k];
next.y = cur.y + dy[k];
next.step = cur.step + 1;
if (IsInBound(next.x, next.y) && !vis[next.x][next.y]
&& maze[next.x][next.y]!='#')
{
vis[next.x][next.y] = 1;
if (maze[next.x][next.y] == 'x')
{
++next.step;
}
q.push(next);
}
}/* End of For */
}/* End of While */
if (isSolve)
{
printf("%d\n", cur.step);
}
else
{
printf("Poor ANGEL has to stay in the prison all his life.\n");
}
}/* BFS */
int main()
{
while (2 == scanf("%d %d", &nNum, &mNum))
{
getchar();
memset(vis, 0, sizeof(vis));
memset(maze, 0, sizeof(maze));
for (i=0; i<nNum; ++i)
{
scanf("%s", maze[i]);
}/* End of For */
for (i=0; i<nNum; ++i)
{
for (j=0; j<mNum; ++j)
{
if (maze[i][j] == 'a')
{
sx = i, sy = j;
}
}
}/* End of For */
BFS();
}/* End of While */
return 0;
}