ACM/ICPC 2003 国内予選
問題C :The Secret Number
動的計画法の問題。数字は右下のマスにのみ連結しているので、二次元配列の左上から順に走査していけばOK。再帰処理で計算すると、タイムオーバーになります(多分w)。
数字列はLong型の範囲(2^63-1)を超えてしまうので、String型で処理します。数字列の大小は桁数と辞書順で判断したんだけど、他に良い方法があるのかな?
- 新しい数字列の方が桁数が多い → 採用
- 新旧の数字列の桁数が同じ → 辞書順で比較
import java.io.*; import java.util.*; public class TheSecretNumber { public static void main(String[] args) { try { // Scanner in = new Scanner(System.in); Scanner in = new Scanner(new File("C.in")); while (true) { int w = in.nextInt(); int h = in.nextInt(); // 終了条件 if (w == 0 && h == 0) break; // matrixの生成 Square[][] mat = new Square[h][w]; for (int dy = 0; dy < h; dy++) { String line = in.next(); for (int dx = 0; dx < w; dx++) { String digit = line.substring(dx,dx+1); mat[dy][dx] = new Square(digit,digit); } } // 数字列はLong型の範囲を超えるので、String型で処理する String max = null; // matrixの探索 // 数字列の比較は、文字数と辞書順で比較する for (int dy = 0; dy < h; dy++) { for (int dx = 0; dx < w; dx++) { // 当該のマスが数字じゃなかったら if (!mat[dy][dx].num.matches("[0-9]")) continue; // 左側のマスのチェック if (dx - 1 >= 0 && mat[dy][dx - 1].num.matches("[0-9]")) { String newSeq = mat[dy][dx - 1].seq + mat[dy][dx].num; if (mat[dy][dx].seq.length() < newSeq.length() || (mat[dy][dx].seq.length() == newSeq.length() && mat[dy][dx].seq.compareTo(newSeq) < 0)) mat[dy][dx].seq = newSeq; // 数字列の先頭が0の場合 if (mat[dy][dx].seq.startsWith("0")) mat[dy][dx].seq = mat[dy][dx].seq.substring(1); } // 上側のマスのチェック if (dy - 1 >= 0 && mat[dy - 1][dx].num.matches("[0-9]")) { String newSeq = mat[dy - 1][dx].seq + mat[dy][dx].num; if (mat[dy][dx].seq.length() < newSeq.length() || (mat[dy][dx].seq.length() == newSeq.length() && mat[dy][dx].seq.compareTo(newSeq) < 0)) mat[dy][dx].seq = newSeq; // 数字列の先頭が0の場合 if (mat[dy][dx].seq.startsWith("0")) mat[dy][dx].seq = mat[dy][dx].seq.substring(1); } // 最大値の保存 if (max == null || (max.length() < mat[dy][dx].seq.length() || (max.length() == mat[dy][dx].seq.length() && max.compareTo(mat[dy][dx].seq) < 0))) max = mat[dy][dx].seq; } } System.out.println(max); } } catch (Exception e) { e.printStackTrace(); } } } class Square { String num; String seq; // コンストラクタ Square(String num,String seq) { this.num = num; this.seq = seq; } }