Hướng dẫn giải của Bedao Mini Contest 07 - ARCHITECT
Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.
Tác giả:
Nhận xét:
- Đa phần các bạn khi nhìn vào đề bài này đều sẽ lầm tưởng để giải được bài này cần ~8~ đến ~9~ mảng cộng dồn cho từng loại một nhưng làm thế thì vô cùng phức tạp. Vì vậy muốn tạo thành một kim tự tháp thì luôn luôn phải thỏa mãn điều kiện rằng , ~X -[ 2 \times (k -1)] > 0~ và ~Y -[ 2 \times (k -1)] > 0~, từ đó, ta chứng minh được ~1 \leq k < \sqrt[3]{5\times10^{5}}~
- Khi chứng minh được ~k~ rất bé như trên bài toán thu về đơn giản chỉ cần xét điều kiện để có thể tạo thành hình kim tự tháp ~X -[ 2 * (k -1)] > 0~ và ~Y -[ 2 * (k -1)] > 0~.
Từ nhận xét, ta thấy khi thỏa mãn điều kiện của kim tự tháp thì chỉ cần chạy từng tầng của kim tự tháp để tính tổng tiền tố với tầng đáy tính từ dưới lên là ~1~. Ở tầng thứ ~i~ ~(1\leq i \leq Z)~ ta tính tổng các ô lập phương tạo thành hình hộp chữ nhật có góc trái trên là {~{ x + (i -1) ; y + (i -1 ) ; z + (i -1) }~} có chiều rộng là ~X -[ 2 * (k -1)]~ , chiều dài là ~Y -[ 2 * (k -1)]~ và chiều cao là ~1~.
Bạn có thể tham khảo cách tính bằng mảng cộng dồn hai chiều tại đây
Code mẫu
#include <bits/stdc++.h> using namespace std; int n, m, k; long long get(vector<vector<long long>>& s, int x, int y, int u, int v) { return s[u][v] - s[x-1][v] - s[u][y-1] + s[x-1][y-1]; } int main() { cin.tie(0)->sync_with_stdio(0); cin >> n >> m >> k; vector<vector<vector<long long>>> a(k+5, vector<vector<long long>> (n+5, vector<long long> (m+5, 0ll))); for (int i = 1; i <= k; ++ i) { vector<vector<long long>>& s = a[i]; for (int j = 1; j <= n; ++ j) for (int h = 1; h <= m; ++ h) { cin >> s[j][h]; s[j][h] += s[j-1][h] + s[j][h-1] - s[j-1][h-1]; } } int ntest; for (cin >> ntest; ntest --;) { int r, c, h, x, y, g; cin >> r >> c >> h >> x >> y >> g; if (x == 0 || y == 0 || h == 0 || g == 0) { cout << -1 << "\n"; continue; } if (h + g - 1 > k) { cout << -1 << "\n"; continue; } long long res = 0; for (int i = g; i <= h + g - 1; ++ i) { if (r < 1 || c < 1 || x > n || y > m) { res = -1; break; } if (x + r - 1 > n || y + c - 1 > m) { res = -1; break; } res += get(a[i], x, y, x + r - 1, y + c - 1); ++ x; ++ y; r -= 2; c -= 2; } cout << res << "\n"; } return 0; }
Bình luận