队列的应用---迷宫问题(3)

题目如下:

在这里插入图片描述

解题思路:

关键就是要利用队列的先进先出的特点,达到广度和深度的搜索,用一个4行2列的二维数组来表示移动的上下左右四个不同方向,还需要一个bool类型的二维数组来标记走过的点避免重复。
先要找到S点,将它放入队列并标记,这是起点,出队,然后判断S点的上下左右四个方向坐标是否越界或者走过,如果能走则将它放入队列,并且记录步数(每当从一点向四周移动一点时,这代表走了一步,并且,该点四周的点记录的步数应该相同),继续出队,判断,入队,步数加1(出队的点基础上),循环下去直到搜索到T点坐标。

解题代码:
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
struct walk 
{
	int x;
	int y;
	int step;
};  //记录点的坐标和到达该点的步数
int t[4][2]={{1,0},{-1,0},{0,1},{0,-1}};  //上下左右四个方向,0列代表行x,1列代表列y,里面的四个坐标可以交换顺序
int areval(char s[100][100],bool flag[100][100],int n,int m,walk S,walk T)
{  //对迷宫进行搜索,找到T点,返回步数
	queue<walk> D;
	D.push(S);  //先将S点入队
	flag[S.x][S.y]=false;  //标记该点为走过
	while(!D.empty())  //队空代表迷宫全部探索完,不能走到T点
	{
		walk e=D.front();  //取队头元素
		D.pop();  //出队
		for(int i=0;i<4;i++)  //对该点的四个方向探索
		{
			walk p;
			p.x=e.x+t[i][0];
			p.y=e.y+t[i][1]; //新的点
			p.step=e.step+1; //步数加1
			if(p.x>=n||p.x<0||p.y>=m||p.y<0) continue;  //判断该点是否越界
			if(s[p.x][p.y]=='#'||flag[p.x][p.y]!=true) continue;  //判断该点是否能走和走没走过
			if(p.x==T.x&&p.y==T.y) return p.step;  //判断是否到了T点,若到了,直接返回步数
			D.push(p);  //将新点入队
			flag[p.x][p.y]=false;  //标记该点走过
		}
	}
	return -1;  //找不到返回-1
}
int main()
{
	char s[100][100];  //记录迷宫
	int n,m;
	while(cin>>n>>m)
	{
		walk S,T;
		bool flag[100][100];  //用来标记是否走过
	    fill(&flag[0][0],&flag[99][99]+1,true);
		for(int i=0;i<n;i++)
		{
		for(int j=0;j<m;j++)
		{
		cin>>s[i][j];
		if(s[i][j]=='S')
		{
			S.x=i;S.y=j;S.step=0;  //记录S点坐标
		}
		if(s[i][j]=='T')
		{
			T.x=i;T.y=j;  //记录T点坐标
		}
		}
		}
		int steps=areval(s,flag,n,m,S,T);
		if(steps<0) cout<<"impossible";
		else cout<<steps;
		cout<<endl; 
	}
	return 0;
} 
后语:

今天ACM竞赛做出了4道题,终于比以前只能做签到题好一些了,一直被ACM竞赛题目虐的失去了信心,今天终于能在其中体验AC的成就感了,曾经的状态又回来了一点,似乎又喜欢上了做题目。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值