[ABC260G] Scalene Triangle Area题解
[ABC260G] Scalene Triangle Area
题意
有一个 XO 组成,对于一个 O,如果它的坐标是
-
u\le x -
v\le y -
(x-u)+\dfrac{(y-v)}{2}<M
给定 O 控制。
思路
1.暴力(虽然也能过)
对于一个 O,它肯定可以影响几行,而每一行也肯定是连续的一段,那么可以枚举行然后计算连续的一段的左端点和右端点,然后前缀和计算(由于后面有正解,这里就不详细解释了)。
#include <iostream>
using namespace std;
const int MaxN = 2010;
int f[MaxN][MaxN], n, m, l, r, q, ans;
char c[MaxN][MaxN];
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> c[i][j], f[i][j] = f[i][j - 1] + (c[i][j] == 'O');
}
}
for (cin >> q; q; q--) {
cin >> l >> r, ans = 0;
for (int i = max(l - m, 1); i <= l; i++) {
int j = max(r - (m - (l - i)) * 2, 0);
(j <= r) && (ans += f[i][r] - f[i][j]);
}
cout << ans << '\n';
}
return 0;
}
2.正解 差分
我们来看这样一组数据
OXXXXXXXX
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
XXXXXXXXX
而
最后反着还原原数组即可。
#include <iostream>
using namespace std;
const int MaxN = 2010;
int n, m, t, l, r;
char c[MaxN][MaxN];
int q[MaxN * 3][MaxN], x[MaxN * 3][MaxN * 5], st[MaxN * 3][MaxN * 5];
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> c[i][j];
if (c[i][j] == 'O') {
q[i][j]++, q[i + m][j]--, x[i][j + 2 * m]--, x[i + m][j]++;
}
}
}
for (int i = 1; i <= n + m; i++) {
for (int j = 1; j <= n + 2 * m; j++) {
x[i][j] += x[i - 1][j + 2];
}
}
for (int i = 1; i <= n + m; i++) {
for (int j = 1; j <= n; j++) {
q[i][j] += q[i - 1][j];
}
}
for (int i = 1; i <= n + m; i++) {
for (int j = 1; j <= n + 2 * m; j++) {
st[i][j] = q[i][j] + x[i][j];
}
}
for (int i = 1; i <= n + m; i++) {
for (int j = 1; j <= n + 2 * m; j++) {
st[i][j] += st[i][j - 1];
}
}
for (cin >> t; t; t--) {
cin >> l >> r;
cout << st[l][r] << '\n';
}
return 0;
}
这是本蒟蒻的第一篇题解,请管理大大放宽放宽吧。