0

これは宿題ではありません。あくまでも練習問題です。

行列が与えられた場合、(0,0) から (N,N) までの可能な脱出ルートの数を見つけます。斜め移動はできません。

「0」の位置は開いたセルを表し、「1」はブロックされたセルを表します。私は (0,0) から旅を始め、(N,N) に到達しなければなりませんでした。

入力形式

最初の行は、行列のサイズを示す単一の正の奇数 T (<= 85) です。T 行が続き、それぞれに '0' または '1' のいずれかである T スペースで区切られた数値が含まれます。

出力フォーマット

(0,0) から (N,N) まで脱出できた方法の数を出力してください。

サンプル入力

7
0 0 1 0 0 1 0
1 0 1 1 0 0 0
0 0 0 0 1 0 1
1 0 1 0 0 0 0 
1 0 1 1 0 1 0
1 0 0 0 0 1 0
1 1 1 1 0 0 0

サンプル出力

4

私の解決策によれば、左 (l)、右 (r)、上 (u)、下 (d) の 4 つの方向を取りました。

問題は、間違った回答またはスタックオーバーフロー エラーが発生することです。何が欠けている?

そして、これはこの質問に対する最適な解決策ですか?

私のソリューション (Java)

import java.io.BufferedReader;
import java.io.InputStreamReader;

class testclass {
int no_of_escapes = 0 ;
int[][] arr;
int matrixlength;
public static void main(String[] args) throws Exception 
{

    testclass obj = new testclass();
    obj.checkpaths(0,0,"");
    System.out.print(obj.no_of_escapes);

}//main

testclass()
{
    try
    {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    matrixlength =Integer.parseInt(br.readLine());      
     arr = new int[matrixlength][matrixlength];
    for( int k = 0; k < matrixlength; k++){

        String str = br.readLine();
        int count = 0;
        for(int j=0 ; j< ((2*matrixlength)-1); j++){
            int v = (int)str.charAt(j) - 48;
            if(v == -16){}
            else{
            arr[k][count] = v;
            count++;
            }

        }//for j

    }//for k

}
catch(Exception e){}
}

public void checkpaths(int m, int n,String direction){

    if((m == matrixlength -1) && (n == matrixlength-1))
    {
        no_of_escapes = no_of_escapes +1;
        return;
    }

    if(!direction.equals("l"))
    {
        if(m < matrixlength && n < matrixlength)
            {
                if((n+1) < matrixlength )
                    {
                        if(arr[m][n+1]==0 )
                            {
                                checkpaths(m,n+1,"r");
                            }
                    }
            }
    }

    if(!direction.equals("u"))
    {
        if((m+1) < matrixlength )
        {
            if(arr[m+1][n]==0 )
            {
            checkpaths(m+1,n,"d");                  
            }
        }
    }

    if(!direction.equals("r"))
    {
        if(m < matrixlength && n < matrixlength)
            {
                if((n+1) < matrixlength )
                    {
                        if(arr[m][n+1]==0 )
                            {
                                checkpaths(m,n+1,"l");
                            }
                    }
            }
    }

    if(!direction.equals("d"))
    {
        if((m-1)>=0)
        {
            if(arr[m-1][n]==0 )
            {
            checkpaths(m-1,n,"u");                  
            }

        }

    }


}
}//class
4

1 に答える 1

2

以下のスニペットに示すように、既にアクセスしたセルをマークするために、ブール値の 2 番目の 2D 配列を保持します。コードの重複を減らすために、コードの他の部分も単純化しました。

もちろん、 を使用してvisitedを初期化したのと同じように、コンストラクターで初期化する必要があります。arrvisited = new boolean[matrixLength][matrixLength]

int[][] arr;
boolean[][] visited;
final int[][] directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};

public boolean isValid(int x, int y) {
    return 0 <= x && x < matrixLength 
        && 0 <= y && y < matrixLength 
        && arr[x][y] == 0
        && !visited[x][y];
}


public void checkPaths(int x, int y) {
    if (x == matrixLength-1 && y == matrixLength-1) {
        no_of_escaped++;
    } else {
        for (int[] d : directions) {
            if (isValid(x + d[0], y + d[1])) {
                visited[x + d[0]][y + d[1]] = true;
                checkPaths(x + d[0], y + d[1]);
                visited[x + d[0]][y + d[1]] = false;
            }
        }
    }
}
于 2013-06-09T13:50:32.063 に答える