看原题戳这儿
显然,这道题是一道正经的签到题
零、写在前面
本来想再做一期( ext{题解 GDFZOJ 2020提高组十连测day4})的,但是无奈本人技术太过于渣,只(A)掉了一题,也就是这一题,所以只能出本题的题解了
前置知识: 字符串的读入、条件语句、循环语句(看到这个就基本上能确定是一道送分题了)
好了,我们进入正文
一、审题
先将题目简化:有一个机器人在(0,0)的位置上,可以输入一段指令使其移动,移动方式如下:若机器人现在在点((x,y))
输入的指令 | 到达的坐标 |
---|---|
(E) | ((x+1,y)) |
(S) | ((x,y-1)) |
(W) | ((x-1,y)) |
(N) | ((x,y+1)) |
若按指令移动之后一个周期之后还未停止运动,就重头再循环一个周期
问(T)步之后机器人所在的位置
数据范围(T le 2 * 10^9) 且( ext{命令串长度}Sle 5,000)
首先一步一步地枚举肯定是不行的,所以要想一个简便一点的算法
二、做题
首先我们用一个数组预处理出一个循环之内机器人可以移动多远,然后再算出有多少个循环,也就是(T/S),然后乘上一个循环能移动的距离,这就是经过(T / S * S)步后机器人所在的位置,然后再暴力一遍剩下的就行了呀,反正这个时候也只剩下不到(S)不了嘛,于是这道题就这么愉快的解决了,时间复杂度(O(S))
三、代码
#include<bits/stdc++.h>
using namespace std;
long long int a,b,c,d,x,y;
struct node{
long long int x,y;
}aa[10001];
char cc[1000001];
int main()
{
scanf("%s",cc);
int l=strlen(cc);
for(int i=0;i<l;++i)
{
if(cc[i]=='E') aa[i+1].x=aa[i].x+1,aa[i+1].y=aa[i].y;
if(cc[i]=='S') aa[i+1].x=aa[i].x,aa[i+1].y=aa[i].y-1;
if(cc[i]=='W') aa[i+1].x=aa[i].x-1,aa[i+1].y=aa[i].y;
if(cc[i]=='N') aa[i+1].x=aa[i].x,aa[i+1].y=aa[i].y+1;
}
// for(int i=1;i<=l;++i) printf("%3d",aa[i].x);printf("
");
// for(int i=1;i<=l;++i) printf("%3d",aa[i].y);printf("
");
scanf("%lld",&a);
x=a/l*aa[l].x,y=a/l*aa[l].y;
a-=a/l*l;
x+=aa[a].x,y+=aa[a].y;
printf("%d %d
",x,y);
return 0;
}
/*
NSWWNSNEEWN
12
*/