3065. 巧虎机器人——行走编程模式(字符数组、字符串的输入)

题目

【问题描述】

以下图(a)所示的巧虎机器人有几种工作模式,其中行走编程模式具有简单的编程功能,能接收前进(F)、后退(B)、左转(L)、右转(R)四种指令,输入一系列指令,然后按下OK键,巧虎机器人就在图(b)所示的地图上从起始位置出发执行指令序列对应的动作,假定机器人最初的朝向是向北。输入地图(包含巧虎的起始位置)和指令序列,输出巧虎的最终位置和朝向。

A-a.png

(a) 巧虎机器人

1606407082285091189.png

(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;
    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值