POJ1573题解

一、题目大意

有一个r*c的网格,网格中每一格都会有一个字符N,S,W,E(N是向上走1格,S是向下走1格,W是向左走1格,E是向右走1格)。有一个机器人将会在网格最上方进入网格(可以定义最上方的那一行为第1行),在指定了入口所在的列数bc之后,它就会从第1行第bc列进入网格,并且根据所到达网格中的字符确定下一步走的方向。机器人最终会遇到两种情况:
1.走出网格。
2.走进循环,也就是会在某几格循环移动。
现在输入r,c,bc,以及网格中的每一个字符,通过编程求出机器人最终会遇到哪种情况

二、思路

1.如果是第一种情况,用ans记录最终步数;如果是第二种情况,ans最终表示为只走一次的步数,再用ans2表示循环步数。
2.map数组记录网格中的每一个字符。
3.开始我只是把vis单纯地用来记录某一格是否已经访问过,但是后来考虑到题目的第二种情况后,觉得vis数组也可以用来记录首次到达某一格经历的步数。
4.map和vis两个数组在分析每一组数据前都要记得清零。
5.只要每一次移动后,所在的那一格(x,y)在网格内,并且没有被访问过,就说明符合题意,ans加1(此时的ans是用来记录累计步数的),并且把ans赋值给vis[x][y],然后根据那一格的字符决定下一步的移动方向。
6.移动后,如果x或y在网格范围之外,就表示走出网格了,输出累计步数即可。
7.移动后,如果发现(x,y)已经访问过,说明走进了循环,经过验算可以得到下面的代码中对ans2和ans的计算方式,然后按题目要求输出即可。

三、代码

#include<iostream>
#include<cstring>
using namespace std;
char map[15][15];
int vis[15][15];
int main()
{
	int r,c,bc,x,y,ans,ans2;
	while(cin >> r >> c >> bc, r||c||bc)
	{
		ans=0; ans2=0;
		memset(map,0,sizeof(map));
		memset(vis,0,sizeof(vis));
		for(int i=1; i<=r; i++)
		{
			for(int j=1; j<=c; j++)
			{
				cin >> map[i][j];
			}
		}
		x=1; y=bc;
		while(x>=1 && x<=r && y>=1 && y<=c && !vis[x][y])
		{
			ans++;
			vis[x][y] = ans;
			switch(map[x][y])
			{
				case 'N': x--; break;
				case 'S': x++; break;
				case 'W': y--; break;
				case 'E': y++; break;
			}
		}
		if(x<1 || x>r || y<1 || y>c)
		{
			cout << ans << " step(s) to exit" << endl;
		}
		else if(vis[x][y])
		{
			ans2 = ans-vis[x][y]+1;
			ans = vis[x][y]-1;
			cout << ans << " step(s) before a loop of " << ans2 << " step(s)" << endl;
		}
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值