AOJ 2015: スクウェア・ルート
問題: Square Route | Aizu Online Judge
解法: 縦と横それぞれについて、作りうる長さとその数を出しておく。作りうる長さは、w1, w1+w2, w1+w2+w3 ... のように連続した辺を足した組み合わせになる。辺の数が1500以下、辺の長さが1000以下なので、辺の種類は1500000以下になる。
ある辺の長さiについて、縦にあるiの数×横にあるiの数だけ、1辺の長さがiの正方形が出来る。
解答コード:
import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { while (true) { int N = nextInt(); if (N == 0) { break; } int M = nextInt(); int[] h = new int[N]; int totalH = 0;// 高さの和を調べておく for (int i = 0; i < h.length; i++) { h[i] = nextInt(); totalH += h[i]; } int[] w = new int[M]; int totalW = 0;// 幅の和も調べておく for (int i = 0; i < w.length; i++) { w[i] = nextInt(); totalW += w[i]; } int[] heightType = new int[totalH + 1];// 作りうる高さの種類 int[] widthType = new int[totalW + 1];// 作りうる幅の種類 for (int i = 0; i < h.length; i++) { int height = h[i]; heightType[height]++; for (int j = i + 1; j < h.length; j++) { height += h[j]; heightType[height]++; } } for (int i = 0; i < w.length; i++) { int width = w[i]; widthType[width]++; for (int j = i + 1; j < w.length; j++) { width += w[j]; widthType[width]++; } } int ans = 0;// 解答 for (int i = 1; i <= Math.min(totalH, totalW); i++) { // ある辺の長さiについて、縦にあるiの数*横にあるiの数だけ、 // 1辺の長さがiの正方形が出来る。 ans += heightType[i] * widthType[i]; } System.out.println(ans); } } static int nextInt() { int c; try { c = System.in.read(); while (c != '-' && (c < '0' || c > '9')) c = System.in.read(); if (c == '-') return -nextInt(); int res = 0; while (c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = System.in.read(); } return res; } catch (IOException e) { e.printStackTrace(); } return -1; } static char nextChar() { try { int b = System.in.read(); while (b != -1 && (b == ' ' || b == '\r' || b == '\n')) ; if (b == -1) return 0; return (char) b; } catch (IOException e) { } return 0; } }