ジャンプ


リンク


https://www.acmicpc.net/problem/1890

質問する


N×Nゲームボードに数字が書いてあります.このゲームの目標は、一番左上から一番右下にジャンプし、ルールに従って行うことです.
各セルの数値は、現在のセルから到達できる距離を表します.右または下にのみ移動する必要があります.0はプロセスをブロックする終点ではなく、現在のセルの数値に従って常に右または下に移動します.一度踊るときは、Uターンしてはいけません.すなわち,1つの格子から右へジャンプする場合と下へジャンプする場合の2つしか存在しない.
プログラムを作成し、ルールに従って左上から右下に移動できるパス数を求めます.

入力


1行目は、ゲームボードのサイズN(4≦N≦100)を与える.次のN行では、各セルの数字はN個です.セルの数値は0以上、9以下の整数で、右下隅のセルは常に0です.

しゅつりょく


最左上隅から最右下隅まで問題ルールに合うパス数を出力します. パス数263
-1以下です.

私の答え

  • 参照コード:https://zoonvivor.tistory.com/1092
  • bfsを使用しようとしたが、アクセスチェックが問題要件と異なるため失敗し、dfsを使用しても同様であった.
  • の方法が見つからなかったので、他の人の解答を見ました.2重for文ですべての配列を巡回します.
  • dpの(0,0)に1を入れ、私が現在アクセスしている場所をdp[i+n][j]と呼び、以前アクセスしていた場所をdp[i][j]と呼び、dp[i+n]+=dp[i][j]のように巡回すると、1つの値が得られます.
  • パスの数値サイズはintを超えるため、パスはlong型であるべきである.したがってdp配列は長いタイプの2次元配列である.
  • コアコード
    for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if(i==N-1&&j==N-1) continue;
                    int next = board[i][j];
                    if (i + next < N) {
                        dp[i + next][j] += dp[i][j];
                    }
                    if (j + next < N) {
                        dp[i][j + next] += dp[i][j];
                    }
                    print();
                }
            }
  • 完全コード
    package Baekjoon.java.silver;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.StringTokenizer;
    //참고코드 : https://zoonvivor.tistory.com/109
    public class boj1890 {
        static int N,board[][];
        static long[][] dp;
        static long answer;
        public static void main(String[] args) throws Exception{
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            N = Integer.parseInt(br.readLine());
            StringTokenizer st;
            board = new int[N][N];
            dp = new long[N][N];
            answer = 0;
            for (int i = 0; i < N; i++) {
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < N; j++) {
                    board[i][j] = Integer.parseInt(st.nextToken());
                }
            }
            dp[0][0]=1;
            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {
                    if(i==N-1&&j==N-1) continue;
                    int next = board[i][j];
                    if (i + next < N) {
                        dp[i + next][j] += dp[i][j];
                    }
                    if (j + next < N) {
                        dp[i][j + next] += dp[i][j];
                    }
                    print();
                }
            }
            System.out.println(dp[N-1][N-1]);
        }
        private static boolean isRange(int a, int b){
            return a>=0&&a<N&&b>=0&&b<N;
        }
        private static void print(){
            for (int i = 0; i <N ; i++) {
                System.out.println(Arrays.toString(dp[i]));
            }
            System.out.println("\n");
        }
    }
  • 結果