[回顧] C035_openj_ミニゲーム(入力に問題がある/先駆者の方向を記録する)

1.問題

ゲームは、w * hの正方形のグリッドに分割された長方形のボードでプレイされます。図に示すように、正方形のグリッドごとにゲームカードを1枚配置できますが、もちろんない場合もあります。

次の条件が満たされている場合、2枚のゲームカードの間にパスがあると信じています。

パスには、直線または水平のセグメントのみが含まれます。パスは他のゲームカードを通過できません。ただし、パスは長方形のプレートから一時的に離れることができます。次に例を示します。
ここに画像の説明を挿入
ここでは、(1、3)と(4、4)のゲームカードを接続できます。(2、3)と(3、4)のゲームカードは接続されていません。これらを接続する各パスは他のゲームカードを通過する必要があるためです。

次に、ミニゲームで、問題を満たし、指定された2つのゲームカードを接続できるパスがあるかどうかを判断する必要があります。

入力

入力には複数のデータセットが含まれます。長方形のプレートは一連のデータに対応します。各データセットに含まれる最初の行には、長方形のプレートの幅と長さをそれぞれ表す2つの整数wとh(1 <= w、h <= 75)が含まれています。次のh行は、各行にw文字が含まれており、長方形のボード上のゲームカードの分布を示します。この場所にゲームカードがあることを示すには「X」を使用し、この場所にゲームカードがないことを示すにはスペースを使用します。

次の各行には、4つの整数x1、y1、x2、y2(1 <= x1、x2 <= w、1 <= y1、y2 <= h)が含まれています。長方形のボード上の2枚のカードの位置を指定します(注:長方形のボードの左上隅の座標は(1、1)です)。入力は、2つのゲームカードの位置が同じでないことを保証します。行に4つのゼロがある場合、これはこのテストデータセットの終わりを意味します。

w = h = 0が1行で指定されている場合、すべての入力が終了したことを意味します。

アウトプット

長方形のボードごとに、「Board #n:」という行を出力します。ここで、nは入力データの数です。次に、テストするゲームカードのグループごとに1行を出力します。この行の最初は "Pair m:"です。ここで、mはテストカードの番号です(各長方形ボードの番号は1から始まります)。次に、接続できる場合は、2つのカードを接続するすべてのパスを見つけ、線分の数が最も少ないパスを含めて、「kセグメント」を出力します。kは、見つかった最適パスに含まれる線分の数です。接続できない場合は、 「不可。」が出力されます。

データの各セットの後に空白行が出力されます。

样例输入
5 4
XXXXX
X   X
XXX X
 XXX 
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0
0 0
样例输出
Board #1:
Pair 1: 4 segments.
Pair 2: 3 segments.
Pair 3: impossible.

二、Solution

方法1:dfs

新しいポイント:

  • 前駆体事前記録方向。現在の方向kが事前と同じである場合、追加の手順は必要ありません。
  • それ以外の場合は、現在の方向をkに更新し、としstep+1ます。

剪定:

  • 現在のステップ値がminより大きい場合は、検索を続ける必要はありません。

入力に問題があります:問題があるかどうかを確認できますか?入力が正しくありません。

import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
	static int ex, ey, R, C;
	static char[][] grid;
	static boolean[][] vis;
	static boolean reach;
	static int min, INF = 0x3f3f3f3f;
	final static int[][] dir = { {0,1},{0,-1},{1,0},{-1,0} };

	static boolean inArea(int x, int y) {
		return x >= 0 && x < R+2 && y >= 0 && y < C+2;
	}
	static void dfs(int x, int y, int step, int pre) {
		if (step > min)
			return;
		if (x == ex && y == ey) {
			if (step < min)
				min = step;
			return;
		}
		for (int k = 0; k < 4; k++) {
			int tx = x + dir[k][0];
			int ty = y + dir[k][1];
			if (!inArea(tx, ty) || vis[tx][ty] || grid[tx][ty] != ' ')
				continue;
			if (tx == ex && ty == ey && grid[tx][ty] == 'X') {
				vis[tx][ty] = true;
				if (pre == k)
					dfs(tx, ty, step, pre);
				else 
					dfs(tx, ty, step+1, k);
				vis[tx][ty] = false;
			}
		}
	}
    public static void main(String[] args) throws IOException {  
        Scanner sc = new Scanner(new BufferedInputStream(System.in));
		int cnt = 1;
		while (true) {
		    C = sc.nextInt();
			R = sc.nextInt();
			if (R == 0 && C == 0)
			    return;
			grid = new char[R+50][C+50];
			for (int i = 0; i < R+2; i++) grid[i][0] = ' ';
			for (int i = 0; i < C+2; i++) grid[0][i] = ' ';
			for (int i = 1; i < R+1; i++) {
				String s = sc.next();
				for (int j = 1; j < C+1; j++) {
					grid[i][j] = s.charAt(j-1);
				}
			}
			for (int i = 0; i < R+2; i++) grid[R+1][i] = ' ';
			for (int i = 0; i < C+2; i++) grid[i][C+1] = ' ';
			int pair = 1;
			while (true) {
				int sx = sc.nextInt();
				int sy = sc.nextInt();
				ex = sc.nextInt();
				ey = sc.nextInt();
				if (sx == 0 && sy == 0 && ex == 0 && ey == 0)
				    break;
				dfs(sx, sy, 0, -1);
				System.out.printf("Board #%d:\n", cnt++);
				if (reach) {
					System.out.printf("Pair %d: %d segments.\n", pair++, min);
				} else {
					System.out.printf("Pair %d: impossible.\n", pair++);
				}
				reach = false;
				min = INF;
			}
			sc.next();
		}
    }
}

複雑さの分析

  • 時間の複雑さ: O()
  • スペースの複雑さ: O()

方法2:


複雑さの分析

  • 時間の複雑さ: O()
  • スペースの複雑さ: O()
元の記事714件を公開 賞賛された199件 50,000件以上の表示

おすすめ

転載: blog.csdn.net/qq_43539599/article/details/105627876