机器清洁工
题目背景:
10.31 NOIP模拟T1
分析:矩阵前缀和,递推
比较显然的矩阵前缀和,先预处理,然后枚举每一个放置点,可以解决的范围是左上角(i - d, j - d)右下角(i + d, j + d)的矩形,直接O(1)计算。
Source:
/*
created by scarlyw
*/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <cctype>
#include <vector>
#include <queue>
#include <set>
#include <ctime>
const int MAXN = 1500 + 10;
const int MAXX = 1025;
int d, n, x, y, z;
int m[MAXN][MAXN];
inline void read_in() {
scanf("%d%d", &d, &n);
for (int i = 1; i <= n; ++i)
scanf("%d%d%d", &x, &y, &z), x++, y++, m[x][y] = z;
for (int i = 1; i <= MAXX; ++i)
for (int j = 1; j <= MAXX; ++j)
m[i][j] = m[i - 1][j] + m[i][j - 1] - m[i - 1][j - 1] + m[i][j];
}
inline int calc(int x1, int y1, int x2, int y2) {
return m[x2][y2] + m[x1 - 1][y1 - 1] - m[x1 - 1][y2] - m[x2][y1 - 1];
}
inline void solve() {
int ans = -1, cnt = 0;
for (int i = 1; i <= MAXX; ++i)
for (int j = 1; j <= MAXX; ++j) {
int x1 = std::max(i - d, 1), y1 = std::max(j - d, 1);
int x2 = std::min(i + d, MAXX), y2 = std::min(j + d, MAXX);
int temp = calc(x1, y1, x2, y2);
(temp > ans) ? (ans = temp, cnt = 1) : (temp == ans ? cnt++ : 0);
}
std::cout << cnt << " " << ans;
}
int main() {
// freopen("cleaner.in", "r", stdin);
// freopen("cleaner.out", "w", stdout);
read_in();
solve();
return 0;
}