巧虎机器人——行走编程模式
题目
【问题描述】
以下图(a)所示的巧虎机器人有几种工作模式,其中行走编程模式具有简单的编程功能,能接收前进(F)、后退(B)、左转(L)、右转(R)四种指令,输入一系列指令,然后按下OK键,巧虎机器人就在图(b)所示的地图上从起始位置出发执行指令序列对应的动作,假定机器人最初的朝向是向北。输入地图(包含巧虎的起始位置)和指令序列,输出巧虎的最终位置和朝向。
(a) 巧虎机器人
(b) 地图
【输入形式】
输入文件包含多个测试数据,每个测试数据包含3部分,第1部分占一行,为两个整数,M N(用空格隔开),2<M, N<=20,表示地图的行和列(行号和列号均从1开始计起);第2部分也占一行,为一行字符串,只包含F、B、L、R四种字符,表示巧虎机器人接收到的指令序列,长度不超过100个字符;第3部分占M行,每行有N个字符,这些字符可能为
点号“.”,表示可通行的方格;
字符“S”,表示巧虎机器人的起始位置;(测试数据保证地图中只有一个“S”)
字符“*”,表示障碍物,不可通行。
输入文件最后一行为“0 0”,代表输入结束。
注意:1) 如果接收到的指令为’B’(后退),则往当前朝向的反方向后退一个方格,但朝向不变;2) 巧虎机器人不能出边界,也不能进入到有障碍物的方格,因此如果执行一个指令后出边界了或进入了有障碍物的方格,则这个指令无效,跳过这个指令,继续执行下一个指令。
【输出形式】
对每个测试数据,输出占一行,为两个整数及一个字符,用空格隔开,表示巧虎机器人最后所处的位置(即行号和列号)及朝向。
注意:用n, e, s, w分别表示朝北、东、南、西。
【样例输入】
5 5
FFLRBFLLRBLLF
…
.*…
…S…
...
…*…
0 0
【样例输出】
1 4 e
【样例说明】
【评分标准】
分析题意
输入数据
1.M、N表示地图的行和列,地图定义为二维数组,行和列均从1开始,所以数组开为[M+1][N+1];2<=N、M<=20;M行N列
2.第二行输入为一串字符串,表示机器人的行径指令,f、b、l、r,分别表示前后左右;不超过一百个字符;
3.第三行为地图,点号“.”,表示可通行的方格;
字符“S”,表示巧虎机器人的起始位置;(测试数据保证地图中只有一个“S”)
字符“*”,表示障碍物,不可通行。
规则:
1.接受指令b 后退,往后面退一格,但不改变朝向
2.巧虎机器人不能出边界,也不能进入有障碍物*的方格,如果有则跳过该指令,执行下一个
3.输出巧虎机器人最终位置,及朝向
4.前进或后退才能移动,左右只改变机器人朝向
思路
简单的操作二维数组,字符的输入,定义一个char变量操控机器人:
循环指令数组,switch不同的指令,进入指令后,再次switch机器人的朝向,进行操作;
前进:
如果朝向北,移动一格,x减一,y不变;
如果朝向南,移动一格,x加一,y不变;
如果朝向西,移动一格,x不变,y减一;
如果朝向东,移动一格,x不变,y加一;
向左向右,只转向,不前进
向左:
如果朝向北,朝向改为w;
如果朝向南,朝向改为e;
如果朝向西,朝向改为s;
如果朝向东,朝向改为n;
向右:
如果朝向北,朝向改为e;
如果朝向南,朝向改为w;
如果朝向西,朝向改为n;
如果朝向东,朝向改为s;
遇到的问题
1.在获取了机器人初始位置后,需要将’S’改为’.’,不然后序执行指令时,判断该点是否是’.’,如果是’s’也可以行进,如果没将’s’改成’.’,就会视为障碍物。
2.字符的输入。
3.switch case 的使用。
4.获取字符数组或字符串长度的函数,strlen(), 头文件为<string.h>;
字符的输入
1. cin>>
用法1: 最基本,也是最常用的用法,输入一个数字
用法2: 结束一个字符串,遇“空格”、TAB/回车结束
2. cin.get()
用法1. cin.get(字符变量名)可以用来接收字符
char ch;
ch=cin.get();//=cin.get(ch)
用法2. cin.get(字符数组名,接收字符数目)用来接收一行字符串,可以接收空格
char a[20];
cin.get(a,20);//有些类似 getline ,可以输入多个单词,中间空格隔开
用法3. cin.get(无参数) 没有参数主要用于舍弃输入流中的 不需要的字符,或者舍弃回车,弥补cin.get(字符数组名,接收字符数目)的不足.
例如:
cin.get(a,5);
cin.get();
cin.get(b,4);
当输入:
adfg
adfjh
输出:a:
adfg
b: adf
3. cin.geline()
//接收一个字符串,可以接收空格并输出
char m[20];
cin.getline(m,5);//接受5个字符到m中,其中最后一个为\0,所以只看到4个字符输出
cin.getline() 实际上接受三个参数,cin.getline(接受字符串到m,接受个数5,结束字符)
//当第三个参数省略时,系统默认为\0 是 /n 换行符
cin.getline(m,5,‘a’) 当输入: jkladfgh 输出:jkl 当输入:qwertyu 输出:qwer
当在多维数组中的时候,也可以用cin.getline(m[i],20)之类的用法:
char m[3][20];
for(int i=0;i<3;i++)
{
cin.getline(m[i],20);
}
4. getline()//接受一个字符串,可以接收空格并输出,需包含#include
string str;
getline(cin,str)
cout<<str<<endl;
在string 类中,可以用str[i]来取str字符串中的第i个字符,同时也可以用char *p指向 &str[i]来取其字符。这里的[]是string的操作符重载,而用指针string *p=&str;则是指向str;访问里面的某个字符时,只能(*p)[i];
cin.getline()类似,但是cin.getline()是属于istream流,而getline()属于string流,是不一样的两个函数
5. gets() //接受一个字符串,可以接收空格并输出,需包含
char m[20]
gets(m);
6. getchar()//接受一个字符,需包含
ch=getchar()//但不能写成getchar(ch) 是c语言函数,c++也兼容
*/
Switch case
switch (expression) {
case constant-expression :
statement(s);
break; /* 可选的 */
case constant-expression :
statement(s);
break; /* 可选的 */
/* 您可以有任意数量的 case 语句 */
default : /* 可选的 */
statement(s);
}
例如:
switch (a){
case 1:
cout<<1<<endl;
break;
case 2:
cout<<2<<endl;
break;
default:break;
}
字符数组和字符串长度获取函数 strlen()
需要引用头文件<string.h>
其他待补充
代码
#include <iostream>
using namespace std;
#include<string.h>
const int n = 30;
const int c = 110;
int main()
{
int M,N;
cin>>M>>N;
while(M!=0 && N!=0)
{
char com[c]; //指令字符数组command
cin>>com;
char cmap[n][n];
int x,y; //记录巧虎机器人的位置
char direct = 'n'; //记录方向,初始方向为北n
for(int i=1;i<=M;i++)
{
for(int j=1;j<=N;j++)
{
cin>>cmap[i][j];
if(cmap[i][j] == 'S')
{
x=i;
y=j;
cmap[i][j] = '.'; //机器人初始坐标已获取,将该格改为'.',表示该格无障碍物
}
}
}
for(int i=0;i<=strlen(com);i++)
{
switch(com[i])
{
case 'F':
switch(direct)
{
case 'n': //朝北
if(x-1>=1 && cmap[x-1][y] == '.') //可以通行
{
x = x-1;
}
break;
case 's': //朝南
if( x+1<=M && cmap[x+1][y] == '.')
{
x = x+1;
}
break;
case 'w'://朝西
if(y-1>=1 && cmap[x][y-1] == '.')
{
y = y-1;
}
break;
case 'e': //朝东
if(y+1<=N && cmap[x][y+1] == '.')
{
y = y+1;
}
break;
}
break;
case 'B': //后退朝向不变
switch(direct)
{
case 'n': //朝北
if(x+1<=M && cmap[x+1][y] == '.')
x=x+1;
break;
case 's': //朝南
if( x-1>=1 && cmap[x-1][y] == '.')
x = x-1;
break;
case 'w'://朝西
if(y+1<=N && cmap[x][y+1] == '.')
{
y = y+1;
direct = 'w';
}
break;
case 'e': //朝东
if(y-1>=1 && cmap[x][y-1] == '.')
{
y = y-1;
direct = 'e';
}
break;
}
break;
case 'L':
switch(direct)
{
case 'n': //朝北
direct = 'w';
break;
case 's': //朝南
direct = 'e';
break;
case 'w'://朝西
direct = 's';
break;
case 'e': //朝东
direct = 'n';
break;
}
break;
case 'R':
switch(direct)
{
case 'n': //朝北
direct = 'e';
break;
case 's': //朝南
direct = 'w';
break;
case 'w'://朝西
direct = 'n';
break;
case 'e': //朝东
direct = 's';
break;
}
break;
default:break;
}
}
cout<<x<<" "<<y<<" "<<direct<<endl;
cin>>M>>N;
}
}