1.タイトルの説明
パベルはグリッド迷路が好きです。グリッド迷路は、各セルが空白または壁であるn×mの長方形の迷路です。両方のセルが空白であり、共通のエッジがある限り、1つのセルから別のセルまで歩くことができます。
Pavelはグリッド迷路を描画し、含まれているすべての空白セルは接続された領域を形成します。つまり、空白のセルから他の空白のセルに移動できます。パベルの迷路の壁が少なすぎると、彼はそれを気に入らない。彼は、k個の空白セルを壁に変換して、残りのすべてのセルが接続された領域を形成できるようにしたいと考えています。彼がこの仕事を達成するのを手伝ってください。
入力
最初の行には3つの整数n、m、k(1≤n、m≤500、0≤k <s)が含まれます。nとmはそれぞれ迷路の高さと幅、kはPavelが参加したい壁の数です、および文字sは、元の迷路内の空白セルの数を示します。
次のn行では、各行にm文字が含まれています。彼らは元の迷路を説明します。行の文字が「。」と等しい場合、対応するセルは空白です。文字が「#」と等しい場合、セルは壁です。
アウトプット
n行を印刷します。各行にはm文字が含まれています。Pavelのニーズを満たす新しい迷路です。壁に変換された元の空白セルを「X」として識別します。他のセルは変更しないでください(つまり、「。」と「#」)。
データ保証:解決策があります。複数のソリューションがある場合、それらのいずれかを出力できます。
输入
3 4 2
#..#
..#.
#...
输出
#.X#
X.#.
#...
输入
5 4 5
#...
#.#.
.#..
...#
.#.#
输出
#XXX
#X#.
X#..
...#
.#.#
第二に、解決策
方法1:dfs
- 質問は答えがなければならないことを確実にし、ある程度の困難を減らします、なぜですか?
- 我々はセットポイント全体で別の場所に移動しますので、他の場所に行くまで深く検索などに行くたびに
X
、数字を保証することができ.
、まだ接続されています。
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static int N, M, k;
static char[][] grid;
static boolean[][] vis;
final static int[][] dir = { {0,1},{0,-1},{1,0},{-1,0} };
static boolean inArea(int x, int y) {
return x >= 0 && x < N && y >= 0 && y < M;
}
static void dfs(int x, int y) {
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] != '.' || vis[tx][ty]) {
continue;
}
vis[tx][ty] = true;
dfs(tx, ty);
}
if (k > 0) {
grid[x][y] = 'X';
k--;
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = sc.nextInt();
M = sc.nextInt();
k = sc.nextInt();
grid = new char[N][M];
vis = new boolean[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);
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (grid[i][j] == '.')
dfs(i, j);
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
System.out.print(grid[x][y]);
}
System.out.println();
}
}
}
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、
上級:質問が回答を保証しない場合、この問題にどのように対処する必要がありますか?
私のアプローチは、次のとおりです。BFSメッシュたら、少なくとも大きさがあるか否かを判断するn*m-k
通信ブロックと通信ブロックマーカーは、最後に再びグリッドを横断し、マークされていない.
ようX
することができます。
方法2:bfs
import java.util.*;
import java.math.*;
import java.io.*;
public class Main{
static int N, M, k;
static char[][] grid;
static boolean[][] vis;
final static int[][] dir = { {0,1},{0,-1},{1,0},{-1,0} };
static int cnt, sum, diff;
static boolean inArea(int x, int y) {
return x >= 0 && x < N && y >= 0 && y < M;
}
static void bfs(int x, int y) {
Queue<int[]> q = new ArrayDeque<>();
q.add(new int[] {x, y});
vis[x][y] = true;
cnt = 1;
while (!q.isEmpty()) {
int[] t = q.poll();
for (int k = 0; k < 4; k++) {
int tx = t[0] + dir[k][0];
int ty = t[1] + dir[k][1];
if (!inArea(tx, ty))
continue;
if (grid[tx][ty] == '.' && !vis[tx][ty]) {
if (cnt == diff) {
return;
}
q.add(new int[]{tx, ty});
vis[tx][ty] = true;
cnt++;
}
}
}
}
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = sc.nextInt();
M = sc.nextInt();
k = sc.nextInt();
grid = new char[N][M];
vis = new boolean[N][M];
int sx = -1, sy = -1;
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] == '.') {
sum++;
sx = i; sy = j;
}
}
}
if (sx == -1 && sy == -1) {
System.out.println(-1);
return;
}
diff = sum - k;
bfs(sx, sy);
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (vis[i][j] && grid[i][j] == '.') {
System.out.print('.');
} else if (!vis[i][j] && grid[i][j] == '.') {
System.out.print('X');
} else {
System.out.print('#');
}
}
System.out.println();
}
}
}
複雑さの分析
- 時間の複雑さ: 、
- スペースの複雑さ: 、