首页 > 搜索 > BFS搜索 > hdu 2102 A计划-最短路径-[解题报告]C++
2013
12-29

hdu 2102 A计划-最短路径-[解题报告]C++

A计划

问题描述 :

可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。

输入:

输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。

输出:

输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。

样例输入:

1
5 5 14
S*#*.
.#...
.....
****.
...#.

..*.P
#.*..
***..
...*.
*.#..

样例输出:

YES

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
char maze[2][15][15];
int len[2][15][15];
int mov[4][2]={{0,-1},{0,1},{-1,0},{1,0}};
void BFS(int x0,int y0,int z0)
{
	int i,p,q,r,a,b,c;
	queue<int> x;queue<int> y;queue<int> z;
	x.push(x0);y.push(y0);z.push(z0);
	while(!x.empty()&&!y.empty()&&!z.empty())
	{
		a=x.front();b=y.front();c=z.front();
		x.pop();y.pop();z.pop();
		for(i=0;i<4;i++)
		{
			p=a+mov[i][0];q=b+mov[i][1];r=c;
			if(maze[r][p][q]=='#')
			{
				if(r==0)
				{
					if(maze[1][p][q]=='#'||maze[1][p][q]=='*'||(len[1][p][q]!=-1&&len[1][p][q]<len[0][a][b]))
						continue;
					else if(len[1][p][q]==-1||len[1][p][q]>=len[0][a][b]+1)
					{
						len[1][p][q]=len[0][p][q]=len[0][a][b]+1;
						x.push(p);y.push(q);z.push(1);
					}
				}
				else
				{
					if(maze[0][p][q]=='#'||maze[0][p][q]=='*'||(len[0][p][q]!=-1&&len[0][p][q]<len[1][a][b]))
						continue;
					else if(len[0][p][q]==-1||len[0][p][q]>=len[1][a][b]+1)
					{
						len[0][p][q]=len[1][p][q]=len[1][a][b]+1;
						x.push(p);y.push(q);z.push(0);
					}
				}
			}
			else if(maze[r][p][q]=='.'||maze[r][p][q]=='P')
			{
				if(len[r][p][q]==-1||len[r][p][q]>=len[r][a][b]+1)
				{
					len[r][p][q]=len[r][a][b]+1;
					x.push(p);y.push(q);z.push(r);
				}
			}
		}
	}
}
int main()
{
	int t,i,j,m,n,a,b,c,k,ans;
	scanf("%d",&t);
	while(t--)
	{
		memset(maze,'\0',sizeof(maze));
		memset(len,-1,sizeof(len));
		scanf("%d%d%d",&m,&n,&k);
		getchar();
		for(i=1;i<=m;i++)
			{for(j=1;j<=n;j++)
			    {cin>>maze[0][i][j];
		           if(maze[0][i][j]=='P')
				   {
					   c=0;a=i;b=j;
				   }
		        }
			}
		for(i=1;i<=m;i++)
			{for(j=1;j<=n;j++)
			    {cin>>maze[1][i][j];
		           if(maze[1][i][j]=='P')
				   {
					   c=1;a=i;b=j;
				   }
		        }
			}
		len[0][1][1]=0;
		BFS(1,1,0);
		ans=len[c][a][b];
		if(ans<=k&&ans!=-1)
		    printf("YES\n");
		else
			printf("NO\n");
	}
	return 0;
}

解题转自:http://blog.csdn.net/hqu_fritz/article/details/8648598


  1. 第二个方法挺不错。NewHead代表新的头节点,通过递归找到最后一个节点之后,就把这个节点赋给NewHead,然后一直返回返回,中途这个值是没有变化的,一边返回一边把相应的指针方向颠倒,最后结束时返回新的头节点到主函数。

  2. 其实国内大部分公司对算法都不够重视。特别是中小型公司老板根本都不懂技术,也不懂什么是算法,从而也不要求程序员懂什么算法,做程序从来不考虑性能问题,只要页面能显示出来就是好程序,这是国内的现状,很无奈。

  3. 第二个方法挺不错。NewHead代表新的头节点,通过递归找到最后一个节点之后,就把这个节点赋给NewHead,然后一直返回返回,中途这个值是没有变化的,一边返回一边把相应的指针方向颠倒,最后结束时返回新的头节点到主函数。