KickStart2020B Robot Path Decoding
KickStart2020B Robot Path Decoding
描述
一个机器人在长宽为 \(10^9\) 的地图上,起点为1,给出一个命令序列:
- N S E W,向对应方向移动一格。
- X(Y) 重复 Y 操作 X 次。
问执行完命令后,该机器人在什么位置。
思路
表达式计算问题,可以用栈,亦可以递归。
代码
// 栈版本
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=2010;
#define pll pair<long long,long long>
#define x first
#define y second
const int M=1e9;
stack<pll> nums;
stack<char> ops;
char c[4]={'N','S','W','E'};
bool isAlpha(char ch){
for(int i=0;i<4;i++){
if(ch==c[i]) return true;
}
return false;
}
pll operator + (pll a,pll b){
return {(a.x+b.x)%M,(a.y+b.y)%M};
}
pll operator * (pll a,pll b){
return {(a.x*b.x)%M,(a.y*b.y)%M};
}
void cal(){
pll a=nums.top();nums.pop();
pll b=nums.top();nums.pop();
char c=ops.top();ops.pop();
pll d;
if(c=='+') {
d=a+b;
}else if(c=='*'){
d=a*b;
}
nums.push(d);
}
int main(){
int t; cin>>t; for(int tt=1;tt<=t;tt++){
while(nums.size()) nums.pop();
while(ops.size()) ops.pop();
string str,str2;
cin>>str2;
for(int i=0;i<str2.size();i++){
if(i>0 && (isAlpha(str2[i])||(isdigit(str2[i]))) && (isAlpha(str2[i-1]) || str2[i-1]==')')){
str+="+";
}else if(str2[i]=='('){
str+="*";
}
str+=str2[i];
}
//cout<<str<<endl;
for(int i=0;i<str.size();i++){
if(str[i]>='0' && str[i]<='9'){
ll t=0;
while(str[i]>='0' && str[i]<='9'){
t=t*10+str[i]-'0';
i++;
}
i--;
nums.push({t,t});
}
else if(isAlpha(str[i])){
if(str[i]=='N'){
nums.push({-1,0});
}else if(str[i]=='S'){
nums.push({1,0});
}else if(str[i]=='W'){
nums.push({0,-1});
}else {
nums.push({0,1});
}
}
else{
char c=str[i];
if(c=='+'){
while(ops.size() && ops.top()!='('){
cal();
}
ops.push(c);
}
if(c=='*'){
while(ops.size()&&ops.top()=='*') cal();
ops.push(c);
}else if(c=='('){
ops.push('(');
}else if(c==')'){
while(ops.top()!='('){
cal();
}
ops.pop();
}
}
}
while(ops.size())cal();
//cout<<nums.size()<<endl;
pll res=nums.top();
ll a=res.x,b=res.y;
a=(a%M+M)%M+1;
b=(b%M+M)%M+1;
printf("Case #%d: %lld %lld\n",tt,b,a);
}
return 0;
}
// 递归版本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ar array
const int M=1e9;
string s;
int ptr;
ar<ll,2> pr(){
ar<ll,2> r={0,0};
while(1){
if(ptr>=s.size()){
break;
}
if(s[ptr]==')') {
break;
}
if(s[ptr]=='N'){
--r[1];
if(r[1]<0){
r[1]+=M;
}
}
else if(s[ptr]=='S'){
++r[1];
if(r[1]>=M){
r[1]-=M;
}
}
else if(s[ptr]=='E'){
++r[0];
if(r[0]>=M){
r[0]-=M;
}
}
else if(s[ptr]=='W'){
--r[0];
if(r[0]<0){
r[0]+=M;
}
}else{
int d=s[ptr++]-'0';
++ptr;
ar<ll,2> b=pr();
r[0]=(r[0]+d*b[0])%M;
r[1]=(r[1]+d*b[1])%M;
}
++ptr;
}
return r;
}
void solve(){
cin>>s;
ptr=0;
ar<ll,2> a=pr();
cout<<a[0]+1<<" "<<a[1]+1<<"\n";
}
int main(){
int t,i=1;
cin>>t;
for(i=1;i<=t;i++){
cout<<"Case #"<<i<<": ";
solve();
}
return 0;
}