AtCoder Beginner Contest #005 D: おいしいたこ焼きの焼き方 (2次元の累積和)
解法
たこ焼き器について、二次元の累積和を求めておく。クエリに対して作れる長方形を全列挙し、その長方形を(x,y)だけ平行移動した時に、長方形内部の美味しさの合計を計算する。
コード
import java.util.Scanner; public class Main { public static void main(String[] args) throws Exception { Scanner sc = new Scanner(System.in); int N = sc.nextInt(); int[][] tMap = new int[N + 1][N + 1]; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { tMap[i + 1][j + 1] = sc.nextInt(); } } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { tMap[i + 1][j + 1] += tMap[i + 1][j] + tMap[i][j + 1] - tMap[i][j]; } } int Q = sc.nextInt(); StringBuilder sb = new StringBuilder(); for (int q = 0; q < Q; q++) { int query = sc.nextInt(); int max = 0; for (int h = 1; h <= N; h++) { // h*wの長方形を考える int w = query / h; w = Math.min(w, N); if (w == 0) { break; } // h*wの長方形をx,yだけ平行移動させた時の長方形内の美味しさの合計を計算する for (int x = 0; h + x <= N; x++) { for (int y = 0; w + y <= N; y++) { int deli = tMap[h + x][w + y] - tMap[x][w + y] - tMap[h + x][y] + tMap[x][y]; max = Math.max(deli, max); } } } sb.append(max + "\n"); } sc.close(); System.out.print(sb.toString()); } }