[バックトラッキング] B030_hdu1010_Tempter of the Bone(dfs +接続の問題(パリティプルーニング))

1.タイトルの説明

Xiao Mingには長い夢があり、目が覚めたとき、彼と彼の友人たちは崩れそうなチェス盤に出会いました。彼らはここから脱出するためにあらゆることをしなければなりませんでした。

長い調査の結果、Xiaomingはボードグリッド上に彼が配置されたオルガンがあり、「チャンスは1つしかありません。出発後t秒でドアが開きます」と彼が配置されたボードはN *であることを発見しました。 Mの長方形で、上、下、左、右に移動できます(障害物はありません)。ボードにはドアがあります。

政府のプロンプトによると、シャオミンは彼と彼の友人がt秒後にドアに到着する必要があることを突然理解しました。そして、これらすべて、後戻りはありません!彼が移動すると、彼がいたポイントは消えてしまい、1秒以上ポイントに留まることができないため、グリッドが爆発します。

大きな脱出が始まりました、Xiaomingと彼の友人たちはこの奇妙なチェス盤を安全に脱出できますか?

入力

テストデータの複数のセットを入力します。各テストケースの最初の行には、チェス盤のサイズとドアが開いている時間を示す3つの整数N、M、およびT(1 <N、M <7; 0 <T <50)が含まれています。次のN行はボードレイアウトを示し、各行にはM文字が含まれています。どこに

  • 「。」:バリアフリーポイント
    「X」:障害物ポイント
    「S」:始点
    「D」:ドア

入力は3つのゼロで終了します。このテストケースは処理する必要はありません。

出力

サンプルのセットごとに1行が出力されます。
Xiaomingが安全にエスケープできる場合は「YES」を出力し、そうでない場合は「NO」を出力します。

Sample Input
4 4 5
S.X.
..X.
..XD
....
3 4 5
S.X.
..X.
...D
0 0 0

Sample Output
NO
YES

第二に、解決策

方法1:DFS検索

  • 通常のdfsは30ptしか取得できません。
  • 小さな剪定:リーチ= trueの場合、検索を続ける必要はありません。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static int N, M, T;
	static int sx, sy, ex, ey;
	static char[][] grid;
	final static int[][] dir = { {0,1},{0,-1},{1,0},{-1,0} };
	static boolean[][] vis;
	static boolean reach;
	
	static boolean inArea(int x, int y) {
		return x >= 0 && x < N && y >= 0 && y < M;
	}
	static void dfs(int x, int y, int t) {
		if (grid[x][y] == 'D') {
		    reach = t == T;
			return;
		}
		if (reach) return;
		for (int k = 0; k < 4; k++) {
			int tx = x + dir[k][0];
			int ty = y + dir[k][1];
			if (!inArea(tx, ty) || grid[tx][ty] == 'X' ||  vis[tx][ty])
			    continue;
			vis[tx][ty] = true;
			dfs(tx, ty, t+1);
			vis[tx][ty] = false;
		}
	}
    public static void main(String[] args) throws IOException {  
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
		while (true) {
			N = sc.nextInt();
			M = sc.nextInt();
			T = sc.nextInt();
			if (N == 0 && M == 0 && T == 0)
				break;
			vis = new boolean[N][M];
			grid = new char[N][M];
			for (int i = 0; i < N; i++) {
				String s = sc.next();
				for (int j = 0; j < M; j++) {
					grid[i][j] = s.charAt(j);
					if (grid[i][j] == 'S') {
					    sx = i; sy = j;
					} else if (grid[i][j] == 'D') {
					    ex = i; ey = j;
					}
				}
			}
			vis[sx][sy] = true;
			dfs(sx, sy, 0);
			System.out.println(reach ? "YES" : "NO");
			reach = false;
		}
    }
}

剪定の場所:

  • プレ剪定:現在の位置(x, y)、移動するステップの現在の数と比較:T-tまた、マンハッタン距離として知られている2点間の最短距離があったabs(sx-ex) + abs(sy-ey)ので、T-t < abs(sx-ex) + abs(sy-ey)時間
    3 3 4
    S X X 
    . X X
    X . D     在这里n*m-obs = 3*3-5 = 4 = t,故不可达
    
  • 奇妙でさえ剪定

複雑さの分析

  • 時間の複雑さ: 2 O(2 ^ n) 、注:バックトラッキングの問題は、通常、複雑さが線形ではありません。
  • スペースの複雑さ: (...)

方法2:bfs

bfsは最短パスを報告する必要があり、最短パスが必要な時間Tであるとは限らないため、これは間違った選択です。


参照ブログ:https://blog.csdn.net/nvliba/article/details/48532709、写真とコードなしのテキスト説明の
ような10評価アドレス:https://vijos.org/d/orina_personal/p/5c4f2bf0f41362860e389f83

元の記事714件を公開 賞賛された199件 50,000件以上の表示

おすすめ

転載: blog.csdn.net/qq_43539599/article/details/105595909
おすすめ