题目的大意就是给你一个地图,地图上不是传统的.和# 等等东西,而是方向N S W E ,你走到那个点,那个点是什么方向就是接下来你走的方向,一开始会给你入口(一开始的方向点),判断能不能走出迷宫(四个边界,走出任意一个都可以),如果走不出去(在地图里面循环的情况)。走出就求出步数,走不出去,就写出一开始走几步就开始了几个一周期的循环(步数表示)。
一个机器人已经被编程成按照其路径上的指令进行操作。机器人下一个移动方向的指令被放置在一个网格中。可能的指示是 N北(上一页)
南部(下页)
东面(页面右侧)
W西(页面左侧)
例如,假设机器人从网格1的北侧(顶部)开始,向南(向下)开始。机器人所遵循的路径如图所示。机器人在离开网格前要经过网格中的10个指令。
比较网格2中发生的情况:机器人只执行一次3个指令,然后开始循环8个指令,并且永远不会退出。
你要写一个程序来决定机器人离开网格需要多长时间,或者机器人是如何循环的。
输入
将有一个或多个网格供机器人导航。每个数据的格式如下。第一行是三个由空格分隔的整数:网格中的行数、网格中的列数以及机器人从北方进入的列数。可能的条目列从左边的一列开始编号。然后是方向指示的行。每个网格将至少有一行,最多有10行和10列指令。指令行只包含N、S、E或W字符,没有空格。输入的结尾由包含0 0 0的行指示。
输出
对于输入中的每个网格,都有一行输出。要么机器人遵循一定数量的指令,从任意一个四面的网格中退出,要么机器人遵循一定数量位置上的指令一次,然后重复某些位置上的指令。下面的示例输入对应于上面的两个网格,并说明了两种输出形式。无论数字是否在1之前,单词“step”总是紧跟“(s)”。
Sample Input
3 6 5 NEESWE WWWESS SNWWWW 4 5 1 SESWE EESNW NWEEN EWSEN 0 0
Sample Output
10 step(s) to exit 3 step(s) before a loop of 8 step(s)
代码:
#include<iostream>
#include<stdio.h>
#include<string>
#include<string.h>
const int maxn=1005;
typedef long long ll;
#include<bits/stdc++.h>
using namespace std;
char maap[maxn][maxn];
int vis[maxn][maxn];
int m,n;
int start;
bool flag=false;
int step;
int loop,beloop;
void dfs(int x,int y,int s)
{
// 先判断越不越界 ,越界直接就可以走出
if(x<0||y<0||x>=m||y>=n)
{
flag=true;
return ;
}
step=s;
if(!flag) //判断是否找到
{
if(!vis[x][y]) //判断是否循环回去了
{
vis[x][y]=s; //标记步数
if(maap[x][y]=='N')
dfs(x-1,y,s+1);
else if(maap[x][y]=='S')
dfs(x+1,y,s+1);
else if(maap[x][y]=='E')
dfs(x,y+1,s+1);
else if(maap[x][y]=='W')
dfs(x,y-1,s+1);
}
else
{
beloop=vis[x][y]-1;
loop=s-vis[x][y];
}
}
}
int main()
{
int i,j;
while(cin>>m>>n>>start)
{
if(m==0&&n==0&&start==0)
break;
flag=false;
memset(vis,0,sizeof(vis));
for(i=0;i<m;i++)
for(j=0;j<n;j++)
cin>>maap[i][j];
dfs(0,start-1,1);
if(flag)
printf("%d step(s) to exit\n",step);
else
printf("%d step(s) before a loop of %d step(s)\n",beloop,loop);
}
return 0;
}
题目要求 如果能走出去,输出步数,如果走不出去,输出2个数据,循环之前走了几步,循环周期是多少。首先看看怎么判断出现循环的情况,拿一个标记数组,走过的点都标记上(就用来装步数的就可以),如果出现循环,就可以判断vis标记数组有没有数据。如果能走出去,就看是否越界出了地图。在DFS函数的开头,就判断是否越界。一越界就直接 一路 return(这个bool 类型的变量用的很好,在往下递归途中 可以判断一下,在输出结果时也可以判断)。接下来就是步数的问题, 递归函数有三个参数,前两个都是坐标,后一个是当前步数,在可以出去的情况下,直接输出这个步数就可以。在不可以出去的情况下,我们需要另外引进两个变量,刚刚进入循环时的 那个步数,这个就是代码放的位置了, 如果已经找到循环的情况,但我们已经把步数给他更新了(一开始已经来过的位置有步数),我们就不能得到那个进来前的步数,怎么办呢,那我们就不更新,在更新之前就判断是不是标记过了。
if(!vis[x][y]) //判断是否循环回去了
{
vis[x][y]=s; //标记步数
if(maap[x][y]=='N')
dfs(x-1,y,s+1);
else if(maap[x][y]=='S')
dfs(x+1,y,s+1);
else if(maap[x][y]=='E')
dfs(x,y+1,s+1);
else if(maap[x][y]=='W')
dfs(x,y-1,s+1);
}
如果标记了,直接这个进来点步数 -1(就是进循环之前步数),总的步数减去已经标记时的步数(到这里时,这个点已经包括到总步数了,减去他就是循环周期了)
else
{
beloop=vis[x][y]-1;
loop=s-vis[x][y];
}
新的写法吧;