Search for a command to run...
Progressive hints first, then the full explanation and implementation when you're ready to cash out.
Review status
AI-generated and still unreviewed. Double-check the details before internalizing them.
Hints
Open only as much as you need to keep the solve alive.
The rhombus centered at is the set of cells whose Manhattan distance from is at most , i.e. cells with . So the problem is really: maximize the sum over a Manhattan ball.
Diamonds are annoying, squares are easy. Try a rotation of coordinates: define something like and . What shape does become there?
Let and . Then in rotated coordinates, Use the identity Thatβs the whole damn trick: a diamond in becomes an axis-parallel square in .
Map every original cell to one point in the rotated grid and store its value there. Some rotated-grid cells do not correspond to real board cells (parity mismatch), but just leave them as β rectangle sums still work.
Build a 2D prefix sum on the rotated grid of size about . For each valid center , query the rectangle in . Check all centers and keep the best. Total complexity is
For a center , the rhombus of size consists exactly of the cells
So the function we need to maximize is
Brute-forcing that sum for every center is hopeless: there are up to centers and each rhombus can contain cells. Thatβs dead on arrival.
This is one of those problems where geometry stops being obnoxious the moment you rotate it.
Define transformed coordinates
The shifts are only there to keep indices positive.
For a fixed center , define
Now let
Then
And here comes the key identity:
Why? If , then ; otherwise . Cute and lethal.
Therefore,
which is the same as
So the rhombus becomes an axis-aligned square in the rotated coordinate system. Nice. The geometry has officially given up.
Create a grid indexed by and put
for the unique cell that maps there.
Some positions do not correspond to any original cell because of parity. Thatβs totally fine: leave them as . Then summing over a rectangle in the rotated grid still gives exactly the sum over the rhombus in the original grid.
The range of both and is at most to , so the rotated grid is only about .
Build the 2D prefix sum of :
Then any rectangle sum is
For center , the needed rhombus sum is just the square
So each candidate center is evaluated in .
Then brute-force all valid centers:
Keep the one with maximum sum.
Each original cell contributes to exactly one rotated cell . For a fixed center ), the condition of belonging to the rhombus is
By the identity above, this is equivalent to
which is exactly membership in the queried rectangle. Therefore the rectangle sum in rotated coordinates equals the rhombus sum in the original grid. Since we evaluate every valid center and pick the maximum, the output is correct.
Let .
So the total complexity is
with memory
With , this is easily fast enough.
Also, yes, the statement says the numbers are non-negative. Cute. We donβt even need that.
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
static ll pref[2005][2005];
int main() {
setIO();
int n, m, k;
cin >> n >> m >> k;
int S = n + m; // max transformed index is n + m - 1
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
ll x;
cin >> x;
int u = i + j - 1;
int v = i - j + m;
pref[u][v] += x;
}
}
for (int i = 1; i <= S; ++i) {
for (int j = 1; j <= S; ++j) {
pref[i][j] += pref[i - 1][j] + pref[i][j - 1] - pref[i - 1][j - 1];
}
}
auto get = [&](int x1, int y1, int x2, int y2) -> ll {
return pref[x2][y2] - pref[x1 - 1][y2] - pref[x2][y1 - 1] + pref[x1 - 1][y1 - 1];
};
ll best = -1;
int ansx = k, ansy = k;
for (int x = k; x <= n - k + 1; ++x) {
for (int y = k; y <= m - k + 1; ++y) {
int u0 = x + y - 1;
int v0 = x - y + m;
ll cur = get(u0 - k + 1, v0 - k + 1, u0 + k - 1, v0 + k - 1);
if (cur > best) {
best = cur;
ansx = x;
ansy = y;
}
}
}
cout << ansx << ' ' << ansy << '\n';
}#include <bits/stdc++.h>
using namespace std;
using ll = long long;
void setIO() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
}
static ll pref[2005][2005];
int main() {
setIO();
int n, m, k;
cin >> n >> m >> k;
int S = n + m; // max transformed index is n + m - 1
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= m; ++j) {
ll x;
cin >> x;
int u = i + j - 1;
int v = i - j + m;
pref[u][v] += x;
}
}
for (int i = 1; i <= S; ++i) {
for (int j = 1; j <= S; ++j) {
pref[i][j] += pref[i - 1][j] + pref[i][j - 1] - pref[i - 1][j - 1];
}
}
auto get = [&](int x1, int y1, int x2, int y2) -> ll {
return pref[x2][y2] - pref[x1 - 1][y2] - pref[x2][y1 - 1] + pref[x1 - 1][y1 - 1];
};
ll best = -1;
int ansx = k, ansy = k;
for (int x = k; x <= n - k + 1; ++x) {
for (int y = k; y <= m - k + 1; ++y) {
int u0 = x + y - 1;
int v0 = x - y + m;
ll cur = get(u0 - k + 1, v0 - k + 1, u0 + k - 1, v0 + k - 1);
if (cur > best) {
best = cur;
ansx = x;
ansy = y;
}
}
}
cout << ansx << ' ' << ansy << '\n';
}