题意:
有一个 n×n 的地块,一个连续每 i 分钟没人经过的地面在第 i 分钟会落上 i 个单位的灰,有人经过时不会落灰但灰也不会清零,在人走后第 i 分钟又会落 i 单位的灰,以此类推。你在这个 n×n 的范围内移动,你的移动轨迹可以描述为一个由N,S,W,E 组成的字符串,每个字母分别表示上、下、左、右。这个人一开始在点(x,y),每一分钟移动一步。求最后每个位置上落下的灰的量。上和右分别表示 y 轴正方向和 x 轴正方向。保证你没有超过移动的范围。
说明/提示:
本题 y 轴朝上,x 轴朝右,样例输出中的左下角表示 (1,1),第一分钟你在初始点处,第二分钟移动到相应的位置,第 m+1 分钟移动到最后一个点,但是总共只有 m 分钟,因此最后一个点不受移动的影响
思路:
定义两个二维数组,p[i][j]表示该位置当前会落下多少灰,ans[i][j]表示每个分钟落灰的总和,每分钟更新p、ans,并移动。注意x,y坐标和数组下标之间的关系。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int N = 51;
void move(int &x, int &y, char c) { //移动
switch (c) {
case 'N': y++; break;
case 'S': y--; break;
case 'W': x--; break;
case 'E': x++; break;
default:
break;
}
}
int main() {
int n, m, x, y;
int ans[N][N], p[N][N];
memset(ans, 0, sizeof(ans)); //初始化
memset(p, 0, sizeof(p));
string s;
cin>>n>>m>>x>>y>>s;
for(int i=0; i<m; i++) {
for(int j=1; j<=n; j++) {
for(int k=1; k<=n; k++) {
if(x == j && y == k) {
p[j][k] = 0; //重置
}
else {
p[j][k]++; //更新
ans[j][k] += p[j][k];
}
}
}
move(x, y, s[i]);
}
for(int i=n; i>=1; i--) { //坐标系中(1,1)为左下角
for(int j=1; j<=n; j++)
cout<<ans[j][i]<<' ';
cout<<endl;
}
}