Thông tin
include <bits/stdc++.h>
using namespace std;
const int MAX = 1005;
int m, n, k; int A[MAX][MAX]; // Vì k <= 1000 nên log2(k) <= 9. Ta chỉ cần khai báo kích thước tầng là 10. int ST[MAX][MAX][10][10];
void build2dsparse_table(int g) { // Bước 1: Khởi tạo trạng thái cơ sở (hình vuông 1x1) for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { ST[i][j][0][0] = A[i][j]; } }
// Bước 2: Quy hoạch động xây dựng bảng
for (int x = 0; x <= g; x++) {
for (int y = 0; y <= g; y++) {
if (x == 0 && y == 0) continue;
for (int i = 1; i + (1 << x) - 1 <= m; i++) {
for (int j = 1; j + (1 << y) - 1 <= n; j++) {
if (x > 0) {
// Gộp theo chiều dọc (hàng)
ST[i][j][x][y] = min(ST[i][j][x - 1][y],
ST[i + (1 << (x - 1))][j][x - 1][y]);
} else {
// Gộp theo chiều ngang (cột) khi x = 0
ST[i][j][x][y] = min(ST[i][j][x][y - 1],
ST[i][j + (1 << (y - 1))][x][y - 1]);
}
}
}
}
}
}
// Hàm truy vấn O(1) lấy min của hình vuông k x k tại góc (r, c) int querymin2d(int r, int c, int g) { int len = 1 << g; int r2 = r + k - len; int c2 = c + k - len;
// Lấy min của 4 hình vuông cỡ 2^g x 2^g ở 4 góc
int ans = min({
ST[r][c][g][g], // Góc trên - trái
ST[r2][c][g][g], // Góc dưới - trái
ST[r][c2][g][g], // Góc trên - phải
ST[r2][c2][g][g] // Góc dưới - phải
});
return ans;
}
int main() { // Tối ưu hóa I/O để đọc ghi tệp nhanh iosbase::syncwith_stdio(false); cin.tie(NULL);
// Đọc và ghi từ tệp theo yêu cầu đề bài
freopen("HINHVUONG.INP", "r", stdin);
freopen("HINHVUONG.OUT", "w", stdout);
if (!(cin >> m >> n >> k)) return 0; [cite: 62]
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
cin >> A[i][j]; [cite: 63]
}
}
// Tính g = log2(k) bằng hàm bitwise __lg
int g = __lg(k);
// Xây dựng bảng thưa 2D
build_2d_sparse_table(g);
int max_weight = -1;
// Duyệt qua tất cả các hình vuông con cỡ k x k hợp lệ
for (int i = 1; i + k - 1 <= m; i++) {
for (int j = 1; j + k - 1 <= n; j++) {
int current_min = query_min_2d(i, j, g);
max_weight = max(max_weight, current_min);
}
}
// Ghi kết quả
cout << max_weight << "\n";
return 0;
}