搜索练习:问题 C: 迷宫营救

题目描述

在1000年以前,小QQ是我国最痴情的剑客。他英俊潇洒,而且机智过人_
突然有一天,小QQ心爱的公主RED被魔王困在了一个巨大的迷宫中。小QQ听说这个消息已经是两天以后了,他知道公主在迷宫中还能坚持T天,他急忙赶到迷宫,开始到处寻找公主的下落。
时间一点一点的过去,小QQ还是无法找到公主。最后当他找到公主的时候,美丽的公主已经死了。从此小QQ郁郁寡欢,茶饭不思,一年后追随公主而去了。T_T
1000年后的今天,公主RED托梦给你,并高速你迷宫的地图和时间T,你希望你帮她判断一下当年小QQ是否有机会在给定的时间内找到公主。

输入

题目包括多组测试数据。
每组测试数据以三个整数N,M,T(0<n, m≤200, t>0)开头,分别代表迷宫的长和高,以及公主能坚持的天数。
紧接着有M行,N列字符,由".","",“P”,"S"组成。其中
“.” 代表能够行走的空地。
"
" 代表墙壁,小QQ不能从此通过。
“P” 是公主所在的位置。
“S” 是小QQ的起始位置。
每个时间段(一天)里小QQ只能选择“上、下、左、右”任意一方向走一步。
输入以0 0 0结束。

输出

如果能在规定时间内救出公主输出“YES”,否则输出“NO”。

样例输入

4 4 10



S**P
0 0 0

样例输出

YES

知识点

广度优先搜索(因为要查找最少的路长)

注意情况


代码片段

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
char maps[205][205];//存放地图
int visit[205][205],f[4][2]={{1,0},{-1,0},{0,-1},{0,1}},N,M,T,xs,ys,xp,yp;
struct W{
	int x,y,n;
};
int bfs(int x,int y)
{
	queue<W> q;
	W front,next;
	front.x=x;front.y=y;front.n=0;
	visit[front.x][front.y]=1;//x,y存入
	q.push(front);//第一个入队
	while(!q.empty())//队列不为空
	{
		W pop=q.front();//弹出队首
		if(pop.x==xp&&pop.y==yp)//找到了*-*
		{
			return pop.n;
		}
		for(int i=0;i<4;i++)//向四个方向找
		{
			int xn=pop.x+f[i][0];
			int yn=pop.y+f[i][1];
			if(xn>=0&&yn>=0&&xn<M&&yn<N&&visit[xn][yn]!=1)//满足入队条件
			{
				W push;
				push.n=pop.n+1;//查找的步数+1
				visit[xn][yn]=1;
				push.x=xn;
				push.y=yn;
				q.push(push);//入队
			}
		}
		q.pop();//用完的队首元素弹出
	}
	return -1;//队列全部查完仍没有找到,说明小Q走向了绝路
}
int main()
{
	while(cin>>N>>M>>T)
	{
		if(N==0&&M==0&&T==0) break;
		memset(visit,0,sizeof(visit));//每次查找置为0
		memset(maps,0,sizeof(maps));//每次查找置为0
		for(int i=0;i<M;i++)
		{
			for(int j=0;j<N;j++)
			{
				cin>>maps[i][j];
				if(maps[i][j]=='S')
				{
					xs=i;ys=j;//小Q位置
				}
				if(maps[i][j]=='*')
				{
					visit[i][j]=1;
				}
				if(maps[i][j]=='P')
				{
					xp=i;yp=j;
				}
			}
		}
		int s=bfs(xs,ys);
		if(s>T||s==-1) cout<<"NO"<<endl;
		else cout<<"YES"<<endl;
	}
}

共同进步呀😊

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值