演習課題「二次元累積和を求める」
整数 n, m と n×m の二次元配列 a が与えられるので、二次元累積和を出力してください。
今回考える累積和は、先頭 0 個の和を考慮するものとします(各行・各列の先頭の値は 0 になります)。
入力を受け取るコードと出力用の関数 print2DArray がすでに用意されているので、コードを書き足してプログラムを完成させてください。
期待する出力値
0 0 0 0 0 0
0 1 3 6 10 15
0 3 8 15 24 35
0 6 15 27 42 60
0 10 24 42 64 90
0 15 35 60 90 125
演習課題「二次元累積和を求める(inclusive scan)」
整数 n, m と n×m の二次元配列 a が与えられるので、二次元累積和を出力してください。
今回考える累積和は、先頭 0 個の和を考慮しないものとします(各行・各列の先頭の値は a の同じ位置にある要素の値に等しくなります)。これについて詳しくは Tips を参考にしてください。
入力を受け取るコードと出力用の関数 print2DArray がすでに用意されているので、コードを書き足してプログラムを完成させてください。
期待する出力値
1 3 6 10 15
3 8 15 24 35
6 15 27 42 60
10 24 42 64 90
15 35 60 90 125
#05:二次元累積和
累積和を二次元配列に応用した、二次元累積和について学習します。
二次元累積和による範囲の和の求め方と同じように考えると、s[i+1][j] + s[i][j+1] - s[i][j] という値は、s[i+1][j+1] から a[i][j] の部分だけ取り除いた太い L 字型の区間の和になっています。 よって、この値に a[i][j] を加算することで s[i+1][j+1] を正しく求めることができます。
要素数 0 個の和を考慮しない累積和の計算を行う場合は、i を 0 から n-1 まで繰り返して s[0][i] = a[0][i], s[i][0] = a[i][0] としたのち、i を 1 から n-1 まで, j を 1 から m-1 まで繰り返して s[i][j] = s[i][j-1] + s[i-1][j] - s[i-1][j-1] + a[i][j] とすることで求めることができます。配列 s のサイズは n×m になることに注意しましょう。
また、元の配列でそのまま計算する場合は、一次元の場合の先頭 0 個の和を考慮しない累積和の計算を各行に対して行ったのち、同じ計算を各列に対しても行うことで、二次元累積和を求めることができます。
具体的には、i を 0 から n-1 まで、j を 1 から m-1 まで繰り返して a[i][j] += a[i][j-1] としたのち、j を 0 から m-1 まで、i を 1 から n-1 まで繰り返して a[i][j] += a[i-1][j] とします。