UVa983 Localized Summing for Blurring
問題
http://uva.onlinejudge.org/external/9/983.html
概要
N×N の正方行列が与えられる。全ての M×M の部分行列において、各値の和を出力せよ。またそれらの合計も出力せよ。合計は 64bit signed integer に収まるものとする。
制約
N <= 1000
解法
(普通の)二次元累積和。終点が決まっているので、2重ループで解ける。(4重ループではない)
反省
本番ははじめから二次元累積和の案が出ていたが、4重ループだと思い込んで考えを詰められなかった。
#include <bits/stdc++.h> using namespace std; #define rep(i,n) for(int i=0; i<(n); i++) const int MAX = 1000; int sum[MAX+10][MAX+10]; int main() { int N, M; bool blank = false; while(scanf("%d%d", &N, &M) != EOF) { if(blank) puts(""); blank = true; rep(i, N) rep(j, N) { scanf("%d", &sum[i][j]); if(i) sum[i][j] += sum[i-1][j]; if(j) sum[i][j] += sum[i][j-1]; if(i&&j) sum[i][j] -= sum[i-1][j-1]; } int64_t total = 0; rep(i, N-M+1) { rep(j, N-M+1) { int curr = sum[i+M-1][j+M-1]; if(i) curr -= sum[i-1][j+M-1]; if(j) curr -= sum[i+M-1][j-1]; if(i&&j) curr += sum[i-1][j-1]; printf("%d\n", curr); total += curr; } } printf("%lld\n", total); } return 0; }