思路:
先求出二维前缀和,再用差分枚举每个点的值
Code:
#pragma GCC optimize(3) #pragma GCC optimize(2) #include <map> #include <set> #include <array> #include <queue> #include <stack> #include <cmath> #include <vector> #include <cstdio> #include <cstring> #include <sstream> #include <iostream> #include <stdlib.h> #include <algorithm> #include <unordered_map> using namespace std; typedef long long ll; typedef pair<int, int> PII; #define Time (double)clock() / CLOCKS_PER_SEC #define sd(a) scanf("%d", &a) #define sdd(a, b) scanf("%d%d", &a, &b) #define slld(a) scanf("%lld", &a) #define slldd(a, b) scanf("%lld%lld", &a, &b) const int N = 5e3 + 10; //4e3 + 10; const ll M = 4e12; const int mod = 1e9 + 7; int n, m, p, q, maxx; int a[N][N], sum[N][N], ans[N][N]; void update(int x, int y) { for (int i = 1; i <= p; i++) { for (int j = 1; j <= q; j++) { ans[x + i - 1][y + j - 1] += a[i][j]; // cout << x + i - 1 << " " << y - 1 + j << " " << ans[x + i - 1][y + j - 1] << endl; maxx = max(maxx, ans[x + i - 1][y + j - 1]); } } } int main() { #ifdef ONLINE_JUDGE #else freopen("/home/jungu/code/in.txt", "r", stdin); // freopen("/home/jungu/code/out.txt", "w", stdout); #endif // ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); sdd(p, q); sdd(n, m); for (int i = 1; i <= p; i++) { for (int j = 1; j <= q; j++) { sd(a[i][j]); sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j]; } } for(int i = 1; i <= n; i ++){ for(int j = 1; j <= m; j ++){ int x1 = min(i, p); int y1 = min(j, q); int x2 = max(0, i - (n - p + 1)) + 1; int y2 = max(0, j - (m - q + 1)) + 1; ans[i][j] = sum[x1][y1] - sum[x2 - 1][y1] - sum[x1][y2 - 1] + sum[x2 - 1][y2 - 1]; maxx = max(maxx, ans[i][j]); } } for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { ans[i][j] = ans[i][j] * 100 / maxx; cout << ans[i][j] << " "; } cout << " "; } return 0; }