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();
}
}
}
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、
方法2:
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、