P8462 奶油蛋糕 题解

前置知识

等差数列求和公式:\(\sum\limits_{i=1}^na_i=\frac{n\times(a_1+a_n)}{2}\)

思路

我们可以考虑模拟珂朵莉的移动,当珂朵莉每移动到一个点时对这个点统计一次答案。由于答案和珂朵莉上一次到达这个点的时间有关,对此我们还要记录每个点的珂朵莉上次到达的时间,这样距离珂朵莉上次抵达当前的点的时间为 \(now-last\)。我们再根据上面的求和公式即可以 \(\mathcal O(1)\) 的时间复杂度统计出答案。注意,由于珂朵莉抵达这个点的当天是不会有奶油积累,所以还要减去当天的值。

输出时要注意,由于这题 Y 轴的正方向为上,所以我们输出行的时候要从第 \(n\) 行开始输出,一直输出到第一行为止。而且在输出之前,还要以和上面相同的方式统计一次答案,因为每个点还会持续积累奶油,不过这里不用减去任何值,因为珂朵莉不会对任何点再产生影响了。

注意这道题先输入的 \(x\)\(y\) 并不是广义的 \(x\)\(y\)

代码

#include <bits/stdc++.h>
#define int long long
using namespace std;
int n, m, x, y, sum[1010][1010], last[1010][1010];
string s;

signed main() {
	scanf("%lld%lld%lld%lld", &n, &m, &y, &x);
	cin >> s;
	for (int i = 0, step = 1; step <= m && i < s.size(); i++, step++) {
		int tmp = step - last[x][y];
		sum[x][y] += tmp * (1 + tmp) >> 1;
		sum[x][y] -= (step - last[x][y]);
		last[x][y] = step;
		if (s[i] == 'N') {
			x++;
		} else if (s[i] == 'S') {
			x--;
		} else if (s[i] == 'W') {
			y--;
		} else if (s[i] == 'E') {
			y++;
		}

	}
	int step = m;
	for (int i = n; i; --i) {
		for (int j = 1; j <= n; j++) {
			int tmp = step - last[i][j];
			sum[i][j] += tmp * (1 + tmp) >> 1;
			printf("%lld ", sum[i][j]);
		}
		putchar('\n');
	}
	return 0;
}
posted @ 2022-08-15 16:27  Dregen_Yor  阅读(59)  评论(0)    收藏  举报