[Dfs] B_CodeForce 377_A Labyrinthe (Problem mit verbundenen Blöcken)

1. Titelbeschreibung

Pavel mag Gitterlabyrinth. Ein Gitterlabyrinth ist ein n × m rechteckiges Labyrinth, in dem jede Zelle entweder leer oder eine Wand ist. Sie können von einer Zelle zur nächsten gehen, solange beide Zellen leer sind und eine gemeinsame Kante haben.

Pavel zeichnet ein Gitterlabyrinth, und alle darin enthaltenen leeren Zellen bilden einen verbundenen Bereich. Mit anderen Worten, Sie können von jeder leeren Zelle zu jeder anderen leeren Zelle wechseln. Wenn Pavel's Labyrinth zu wenig Wände hat, mag er es nicht. Er hofft, k leere Zellen in Wände umwandeln zu können, damit alle verbleibenden Zellen noch einen verbundenen Bereich bilden können. Bitte helfen Sie ihm, diese Aufgabe zu erfüllen.

Eingabe

Die erste Zeile enthält drei ganze Zahlen n, m, k (1 ≤ n, m ≤ 500, 0 ≤ k <s), wobei n und m die Höhe bzw. Breite des Labyrinths sind und k die Anzahl der Wände ist, die Pavel verbinden möchte Und der Buchstabe s gibt die Anzahl der leeren Zellen im ursprünglichen Labyrinth an.

In den nächsten n Zeilen enthält jede Zeile m Zeichen. Sie beschreiben das ursprüngliche Labyrinth. Wenn ein Zeichen in einer Zeile gleich "." Ist, ist die entsprechende Zelle leer. Wenn das Zeichen gleich "#" ist, ist die Zelle eine Wand.

Ausgabe

Drucken Sie n Zeilen, wobei jede Zeile m Zeichen enthält: ein neues Labyrinth, das die Anforderungen von Pavel erfüllt. Identifizieren Sie die ursprünglichen leeren Zellen, die in Wände konvertiert wurden, als "X". Andere Zellen müssen unverändert bleiben (dh "." Und "#").

Datensicherung: Es gibt eine Lösung. Wenn es mehrere Lösungen gibt, können Sie eine davon ausgeben.

输入
3 4 2
#..#
..#.
#...
输出
#.X#
X.#.
#...

输入
5 4 5
#...
#.#.
.#..
...#
.#.#
输出
#XXX
#X#.
X#..
...#
.#.#

Zweitens die Lösung

Methode 1: dfs

  • Die Frage stellt sicher, dass es eine Antwort geben muss, die die Schwierigkeit bis zu einem gewissen Grad verringert. Warum?
  • Jedes Mal , wenn wir so weit wie tief Suche gehen woanders hin gehen, so dass wir an anderer Stelle im ganzen Satz Punkt gehen werden X, kann garantieren , die Figur .ist noch angeschlossen.
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();
		}
    }
}

Komplexitätsanalyse

  • Zeitliche Komplexität: Die ( n × m ) O (n × m)
  • Raumkomplexität: Die ( n × m ) O (n × m)

Erweitert: Wenn die Frage keine Antwort garantiert, wie sollten Sie mit diesem Problem umgehen?
Mein Ansatz ist: sobald die BFS Netz, bestimmt , ob es zumindest die Größe eines n*m-kKommunikationsblock und Kommunikationsblock Markers und schließlich das Gitter wieder durchquert, nicht markiert , .wie Xsein kann.


Methode 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();
		}
    }
}

Komplexitätsanalyse

  • Zeitliche Komplexität: Die ( n × m ) O (n × m)
  • Raumkomplexität: Die ( n × m ) O (n × m)
Veröffentlicht 714 Originalarbeiten · erntete Lob 199 · betrachtet 50000 +

Ich denke du magst

Origin blog.csdn.net/qq_43539599/article/details/105602743
Empfohlen
Rangfolge