题解 GDFZOJ 【2314】 东风谷早苗

看原题戳这儿

显然,这道题是一道正经的签到题

零、写在前面

原比赛链接

本来想再做一期\(\text{题解 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\)\(\text{命令串长度}S\le 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("\n");
//	for(int i=1;i<=l;++i) printf("%3d",aa[i].y);printf("\n");
	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\n",x,y);
	return 0;
}
/*
NSWWNSNEEWN
12
*/
posted @ 2020-08-04 10:10  zhnzh  阅读(177)  评论(0编辑  收藏  举报