洛谷 U123017 机器人题解

1.题目描述

机器人会按照输入的指令进行移动,命令包括’E’,‘S’,‘W’,'N’四种,分别对应东南西北。执行某个命令时它会消耗1秒钟向对应的方向移动一格单位。

在0时刻机器人位于(0,0)。
如果遇到’E’命令,向右一个单位,即到达(1,0)。如果遇到’S’命令,向下一个单位,即到达(0,-1)。如果遇到’W’命令,向左一个单位,即到达(-1,0)。如果遇到’N’命令,向上一个单位,即到达(0,1)。

作为新型机器人,它可以执行指令串,从指令串的第一个指令开始执行,如果执行完了最后一个指令,又回到头执行第一个执行,也就是从头开始循环。

求t秒后机器人所在位置坐标。

输入格式

第一行一个字符串,表示指令串

第二行为时间t

输出格式

输出t秒后机器人的坐标位置

样例 #1

样例输入 #1
NSWWNSNEEWN
12
样例输出 #1
-1 3

提示

对于60%的数据, 1 ≤ 1\le 1 t ≤ t\le t 2 × 1 0 5 2\times10^5 2×105,且命令长度 ≤ 5000 \le5000 5000

对于100%的数据, 1 ≤ 1\le 1 t ≤ t\le t 2 × 1 0 9 2\times10^9 2×109,且命令长度 ≤ 5000 \le5000 5000


2.读入指令

根据题目可得:机器人初始位置位于(0,0)。读入一串字符串作为指令。在读入 N 时,向上一个单位;在读入 S 时,向下一个单位;在读入 W 时,向左一个单位;在读入 E 时,向右一个单位。

即当初始位置位于(0,0)时,机器人得到不同指令后移动方式如表格所示:

指令横坐标( x x x)纵坐标( y y y)
N不变+1
S不变-1
W-1不变
E+1不变

根据上述内容,可以写出如下的for循环:

string str; // 定义字符串 str 用于存储指令序列
int t; // 定义整型变量 t 用于存储时间
for (int i=1;i<=t;i++){
           // 根据当前指令更新机器人的位置
           if(str[i-1]=='E'){
               x++; // 向东移动
           }
           else if(str[i-1]=='S'){
               y--; // 向南移动
           }
           else if(str[i-1]=='W'){
               x--; // 向西移动
           }
           else{
               y++; // 向北移动
           }
       }

这时候,你就完成了此题的基础部分。

3.判断指令长度

题中明确给出了这样的内容:

从指令串的第一个指令开始执行,如果执行完了最后一个指令,又回到头执行第一个执行,也就是从头开始循环

因此,我们需要分两类进行讨论:

  • 指令数量大于等于时间
  • 指令数量小于时间

· 指令数量大于等于时间

直接使用刚才的for循环即可。

if (str.size()>t){
       // 循环执行指令序列,直到时间t
       for (int i=1;i<=n;i++){
           // 根据当前指令更新机器人的位置
           if(str[i-1]=='E'){
               x++; // 向东移动
           }
           else if(str[i-1]=='S'){
               y--; // 向南移动
           }
           else if(str[i-1]=='W'){
               x--; // 向西移动
           }
           else{
               y++; // 向北移动
           }
       }
       // 输出机器人在时间t后的位置
       cout<<x<<' '<<y;
   }

· 指令数量小于时间

此时,先执行完整个字符串。计算循环执行的次数和剩余时间后,累加循环执行后的位置,再得到结果。

// 如果指令序列的长度不大于时间t,先执行完整个序列
       for(int i=1;i<=str.size();i++){
           if(str[i-1]=='E'){
               x++;
           }
           else if(str[i-1]=='S'){
               y--;
           }
           else if(str[i-1]=='W'){
               x--;
           }
           else{
               y++;
           }
       }
       // 计算循环执行的次数和剩余时间
       int rest=n % s.size(); // 剩余时间
       t /= s.size(); // 循环执行的次数
       int newx,newy; // 用于存储循环后的位置
       // 累加循环执行后的位置
       for(int i=1;i<=n;i++){
           newx+=x;
           newy+=y;
       }
       // 根据剩余时间更新位置
       for(int i=1;i<=rest;i++){
           if (str[i-1]=='E'){
               newx++;
           }
           else if(s[i-1]=='S'){
               newy--;
           }
           else if(s[i-1]=='W'){
               newx--;
           }
           else{
               newy++;
           }
       }
       // 输出最终位置
       cout<<newx<<' '<<newy;
   }

4.最终代码

代码含语法错误请勿照抄 \textcolor{#e9e9e9}{代码含语法错误请勿照抄} 代码含语法错误请勿照抄

#include<bits/stdc++.h>
using namespace std;
string str; // 定义字符串str用于存储指令序列
int t; // 定义整型变量t用于存储时间
int x,y; // 定义整型变量x和y用于存储机器人的坐标

// 主函数
int main(){
   // 读取指令序列和时间t
   cin>>str>>t;
   // 如果指令序列的长度大于时间t
   if (str.size()>t){
       // 循环执行指令序列,直到时间t
       for (int i=1;i<=t;i++){
           // 根据当前指令更新机器人的位置
           if(str[i-1]=='E'){
               x++; // 向东移动
           } else if(str[i-1]=='S'){
               y--; // 向南移动
           } else if(str[i-1]=='W'){
               x--; // 向西移动
           } else{
               y++; // 向北移动
           }
       }
       // 输出机器人在时间t后的位置
       cout<<x<<''<<y;
   }
   else{
       // 如果指令序列的长度不大于时间t,先执行完整个序列
       for(int i=1;i<=str.size();i++){
           if(str[i-1]=='E'){
               x++;
           } else if(str[i-1]=='S'){
               y--;
           } else if(str[i-1]=='W'){
               x--;
           } else{
               y++;
           }
       }
       // 计算循环执行的次数和剩余时间
       int rest=t%str.size(); // 剩余时间
       t/=str.size(); // 循环执行的次数
       int newx,newy; // 用于存储循环后的位置
       // 累加循环执行后的位置
       for(int i=1;i<=t;i++){
           newx+=x;
           newy+=y;
       }
       // 根据剩余时间更新位置
       for(int i=1;i<=rest;i++){
           if(str[i-1]=='E'){
               newx++;
           } else if(str[i-1]=='S'){
               newy--;
           } else if(str[i-1]=='W'){
               newx--;
           } else{
               newy++;
           }
       }
       // 输出最终位置
       cout<<newx<<''<<newy;
   }
   return 0;
}

5.生长思考

我们在先遇到 N ( E ),再遇到 S ( W )的情况下,其实无需进行任何操作。因此,我们可以使用类似洛谷 P1739 表达式括号匹配这题的方法解出此题。

生长思考不提供代码 \textcolor{#e9e9e9}{生长思考不提供代码} 生长思考不提供代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值