链接:https://www.nowcoder.com/acm/contest/164/B
来源:牛客网
小A站在一个巨大的棋盘上。这个棋盘可以看成是一个网格图。这个网格图的大小为n*m。左上角坐标为(1,1),右下角坐标为(n,m)。这个棋盘很特别,他每行每列都是一个环。具体来说,当小A站在第一行,他往上走的时候,他会走到第n行,站在第n行往下走会走到第一行。对于第一列和第m列类似。小A在棋盘上可以上下左右走,假设他站在位置(i,j),向上走,会走到(i-1,j),向下回到(i+1,j),向左到(i,j-1),向右到(i,j+1)。注意由于棋盘是循环的,他不会走出这个棋盘。
现在小A有一个固定的行走序列S,代表他每一步走的方向,U代表向上,D代表向下,L代表向左,R代表向右。比如小A一开始在(1,1),棋盘大小为3*4。行走序列为UULRD。那么他会依次经过(3,1),(2,1),(2,4),(2,1),(3,1)。但小A觉得只走一遍S太无聊,因此他会重复走这个序列T次。比如上面的例子,当T=2时,真正的行走序列为UULRDUULRD。
小A有q个备选的起点位置。他一开始先给定你棋盘大小与行走序列,对于每个起点位置,他想知道,他沿着序列走,最终会走到哪个位置停下。
第一行三个整数n,m,T。 接下来一行一个字符串S,代表行走序列。注意行走序列在真实走的时候要重复T次。 接下来一个整数q。 接下来q行,每行两个整数x,y,代表小A的一个备选起点。
输出q行,每行两个整数,输出对于这个起点,最后的终点是哪里。
示例1
复制
3 6 4 DUUUDLLLLR 3 3 2 2 5 1 4
复制
2 2 1 5 3 4
20%: |S| * T <= 10^6, q = 1 40%: |S| * T <= 10^6, q <= 10^5 60%: |S|, T <= 10^5, q <= 10^5 100%: 1 <= T,n,m <= 10^9, 1 <= x <= n, 1 <= y <= m. 1<= q, |S| <= 10^5 其中|S|代表S的长度。
这道题按照他所说的步骤模拟即可,不过有几个地方需要注意一下,我们可以直接提前处理好x方向和y方向每个地方一共要走多少步,和自己超出棋盘范围的情况的处理。
#include
using namespace std;
typedef long long ll;
ll n,m,T;
string s;
int main(){
while(~scanf("%d %d %d",&n,&m,&T)){
cin>>s;
ll dx = 0,dy = 0;
int len = s.length();
for(int i = 0; i < len; i++){
if(s[i] == 'D') dx++;
if(s[i] == 'U') dx--;
if(s[i] == 'L') dy--;
if(s[i] == 'R') dy++;
}
dx *= T;
dy *= T;
while(dx < 0 || dx > n) dx = (dx + n) % n;
while(dy < 0 || dy > m) dy = (dy + m) % m;
int q;
scanf("%d",&q);
while(q--){
int a, b;
scanf("%d %d",&a, &b);
a += dx;
b += dy;
a = (a + n*2) % n;
b = (b + m*2) %m;
if(a == 0) a = n;
if(b == 0) b = m;
printf("%d %d\n",a,b);
}
}
return 0;
}