走丢的小信题解

时间:1s 空间:256M

题目描述:

小信出门帮妈妈买菜,不小心迷路了。小信身上带着定位装置,但是装置只显示小信行动的方向,每当小信朝着与原先方向不同的方向走了一步时,定位装置会发出信号。也就是说小信至少会朝着定位装置发出信号的方向走一步。

现在妈妈收到了装置发出的q个信号,信号是东(EAST),南(SOUTH),西(WEST),北(NORTH)中的一种,妈妈想知道小信可能在哪些位置。

输入格式:

第一行包含两个整数n,m表示城市的地图大小。

接下来n 行 m 列的地图,'.' 表示空地,'X'表示建筑物,'*'表示小信出发的位置,保证输入只有一个'*'。

接下来一行包含一个整数 q,表示妈妈收到的信号个数。

接下来 q 行,每行一个字符串,是东南西北中的一种。保证任意两个连续的信号不会相同。

输出格式:

输出初始地图,并把小信可能的所在地标记成 '*'

样例1输入:

4 5

.....

.X...

...*X

X.X..

3

NORTH

WEST

SOUTH

样例1输出:

.....

*X*..

*.*.X

X.X..

 

约定与提示:

对于100%的数据,1\le n,m \le 50,1\le q\le 1000

数据保证合法,也就是说不会出现像下面这种:小信完全不能动,但是还有信号发出的情况。

错误的数据:

3 3
.X.
X*X
.X.
1
NORTH

主要思路:

我们可以用bfs的做法,用三维vis来存储,前两维来存储坐标,第三维存储操作次数。

结和代码使用更佳。

代码(有部分注释)
 

#include<bits/stdc++.h>
using namespace std;  
#define ri register int
#define makedx4 int dx[]={1,-1,0,0}
#define makedy4 int dy[]={0,0,1,-1}
#define makedx8 int dx1[]={0,-1,0,1,1,-1,1,-1}
#define makedy8 int dy1[]={-1,0,1,0,1,-1,-1,1}
makedx4;
makedy4;
struct node{
	int x,y,id;
};
queue<node> q;
int n,m;
char a[60][60];
int dir[1010];//dir来存储方向例如dir[1] = 南,要和dx,dy对应 
int vis[60][60][1010];//vis数组 
int main()
{
	cin>>n>>m;
	int sx,sy;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
			if(a[i][j] == '*')
			{
				a[i][j] = '.';//把起点变成普通点 
				sx = i;
				sy=j;
				//记录起点坐标 
			}
		}
	}
	int q1;
	cin>>q1;
	//q1个方向 
	for(int i=1;i<=q1;i++)
	{
		string s;
		cin>>s;
		if(s[0] == 'N')
		{
			dir[i] = 1;
		}
		if(s[0] == 'S')
		{
			dir[i] = 0;
		}
		if(s[0] == 'E')
		{
			dir[i] = 2;
		}
		if(s[0] == 'W')
		{
			dir[i] = 3;
		}
	}
	vis[sx+dx[dir[1]]][sy+dy[dir[1]]][1] = 1;//第一个操作,id=1
	q.push({sx+dx[dir[1]],sy+dy[dir[1]],1});//放入队列 
	while(!q.empty())
	{
		node tmp = q.front();
		q.pop();
		int x = tmp.x;
		int y = tmp.y;
		int id = tmp.id;
		//提取信息↑ 
		for(int i=0;i<4;i++)
		{
			int tx=x+dx[i],ty=y+dy[i];
			if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]!='.')//判断可否走 
			{
				continue;
			}
			if(i == dir[id]&&!vis[tx][ty][id])//可以选择继续朝这个方向走 
			{
				vis[tx][ty][id] = 1;
				q.push({tx,ty,id});//加入队列 
			}
			if(id+1<=q1&&i == dir[id+1]&&!vis[tx][ty][id+1])//也可以选择执行下一个造作方向 
			{
				vis[tx][ty][id+1] = 1;
				q.push({tx,ty,id+1});
			}
		}
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			if(vis[i][j][q1])//如果当过终点 
			{
				a[i][j] = '*';//变为* 
			}
			cout<<a[i][j];//输出 
		}
		cout<<'\n';
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值