hdu2012- A计划

Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
Submit
 
Status
Description
可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。
 
Input
输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小N*M(1 <= N,M <=10)。T如上所意。接下去的前N*M表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。
 
Output
如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。
 
Sample Input
1
5 5 14
S*#*.
.#...
.....
****.
...#.


..*.P
#.*..
***..
...*.
*.#..
 
Sample Output

YES



思路:很水的一道bfs,居然wa了好多次,太弱了,题目意思其实不是在t时刻找到而是只要在之前能找到就行。。还有一个坑如果上下两层都是传送门的时候就不能传送 相当于是墙了。直接求最短路就行了 也不用什么优化


#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
int vis[2][20][20],last[3],st[100000][3],n,m,ans[100000];
char map[2][20][20];
int a[4] = {0,0,-1,1}, b[4] = {1,-1,0,0};
int bfs()
{
    int begin = 0,end = 1,i;
	while (begin < end)
	{
		if(st[begin][0] == last[0]&&st[begin][1] == last[1]&&st[begin][2] == last[2])  //找到终点
			return ans[begin];
		for(i = 0; i < 4; i++)
		{
		    int q = st[begin][1] + a[i];
			int w = st[begin][2] + b[i];
			int z = st[begin][0];
			if(q >=0 && q < n&&w >= 0 &&w < m&&vis[z][q][w] == 0&&map[z][q][w] != '*')  //判断是否为墙是否超边界是否之前走过
			{
			     if(map[z][q][w] == '#')                                                 //如果是传送门判断传送门在第一层还是第二层然后两层都标记
				 {
				     if(z == 0)
					 {
					     if(map[z+1][q][w] !='*'&&vis[z+1][q][w] == 0)
						 {
						     st[end][0] = z + 1;
							 st[end][1] = q;
							 st[end][2] = w;
							 vis[z+1][q][w] = 1;
							 vis[z][q][w] = 1;
							 ans[end++] = ans[begin] + 1;
						 }	 
					 }
					 if(z == 1)
					 {
						if(map[z-1][q][w] !='*'&&vis[z-1][q][w] == 0)
						{
						     st[end][0] = z -1;
							 st[end][1] = q;
							 st[end][2] = w;
							 vis[z-1][q][w] = 1;
							 vis[z][q][w] = 1;
							 ans[end++] = ans[begin] + 1;
						}
					}	 
				 }
				 else                                                                     //否则直接入队
				 {
				     st[end][0] = z;
					 st[end][1] = q;
					 st[end][2] = w;
					 vis[z][q][w] = 1;
					 ans[end++] = ans[begin] + 1;
				 }
			}
		}
	    begin++;
	}
	return -1;
}
int main()
{
	int t,T;
	cin>>T;
	while (T--)
	{
		int i,j,k;
		scanf("%d %d %d",&n,&m,&t);
		memset(ans,0,sizeof(ans));
	    memset(vis,0,sizeof(vis));
		memset(map,0,sizeof(map));
		for(k = 0; k < 2; k++)
		{    getchar();
		for(i = 0; i < n;i++)
		{
		    for(j = 0; j < m; j++)
			{
			    scanf("%c",&map[k][i][j]);
				if(map[1][i][j] == '#'&&map[0][i][j] == '#')
				{
				     map[1][i][j] = '*';
					 map[0][i][j] = '*';
				}
				    
				if(map[k][i][j] == 'P')
				{
				    last[0] = k;
					last[1] = i;
					last[2] = j;
				}
			}
			getchar();
		}
		}
		st[0][0] = 0;
		st[0][1] = 0;
		st[0][2] = 0;
		vis[0][0][0] = 1;
		int e;
		e = bfs();
		if(e <= t&&e!=-1)
			cout<<"YES"<<endl;
		else 
			cout<<"NO"<<endl;
	}
    return 0;
}


 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值