3 ๋ถ„ ์†Œ์š”

๐Ÿ“ [SW_5656] ๋ฒฝ๋Œ ๊นจ๊ธฐ

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;

public class Solution {
	static StringTokenizer st;
	static int N, W, H, min;
	// ์˜ค๋ฅธ์ชฝ, ์™ผ์ชฝ, ์•„๋ž˜, ์œ„
	static int[] dr = { 1, -1, 0, 0 };
	static int[] dc = { 0, 0, 1, -1 };

	static class Point {
		int r, c, cnt;

		public Point(int r, int c, int cnt) {
			super();
			this.r = r;
			this.c = c;
			this.cnt = cnt;
		}
	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();

		int t = Integer.parseInt(br.readLine());

		for (int tc = 1; tc <= t; tc++) {
			sb.append("#").append(tc).append(" ");
			st = new StringTokenizer(br.readLine(), " ");

			// ๊ตฌ์Šฌ ๋†“๋Š” ํšŸ์ˆ˜
			N = Integer.parseInt(st.nextToken());

			// ๊ฐ€๋กœ
			W = Integer.parseInt(st.nextToken());

			// ์„ธ๋กœ
			H = Integer.parseInt(st.nextToken());

			int[][] map = new int[H][W];

			for (int i = 0; i < H; i++) {
				st = new StringTokenizer(br.readLine(), " ");
				for (int j = 0; j < W; j++) {
					map[i][j] = Integer.parseInt(st.nextToken());
				}
			}

			min = Integer.MAX_VALUE;
			go(0, map);
			sb.append(min).append("\n");

		}
		System.out.println(sb);
	}

	// ์ค‘๋ณต์ˆœ์—ด ์ด์šฉํ•˜์—ฌ ๊ตฌ์Šฌ ๋˜์ง€๊ธฐ
	// ๋ฒฝ๋Œ์ด ๋‹ค ๋ถ€์„œ์กŒ์œผ๋ฉด true, ์•„๋‹ˆ๋ฉด false
	static boolean go(int count, int[][] map) {
		// ์ค‘๋ณต์ˆœ์—ด ๊ตฌ์กฐ

		int result = getRemain(map);

		// ๋ชจ๋“  ๋ฒฝ๋Œ์ด ๋‹ค ๋ถ€์„œ์กŒ๋‹ค๋ฉด
		if (result == 0) {
			min = 0;
			return true;
		}

		// ๋ชจ๋“  ๊ตฌ์Šฌ์„ ๋˜์กŒ๋‹ค๋ฉด
		if (count == N) {
			min = Math.min(min, result);
			return false;
		}

		int[][] newMap = new int[H][W];

		// 0์—ด๋ถ€ํ„ฐ W-1์—ด๊นŒ์ง€ ๊ตฌ์Šฌ ๋˜์ ธ๋ณด๊ธฐ
		for (int c = 0; c < W; c++) {

			// ๊ตฌ์Šฌ์— ๋งž๋Š” ๋ฒฝ๋Œ ์ฐพ๊ธฐ
			int r = 0;
			// ๋นˆ๊ณต๊ฐ„์ด๋ฉด ๊ณ„์† ์•„๋ž˜๋กœ
			while (r < H && map[r][c] == 0)
				++r;

			// ํ–‰์ด ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚˜ ๋๋‚ฌ๋‹ค๋ฉด ํ•ด๋‹น ์—ด์€ ๋ฒฝ๋Œ์ด ์—†์Œ
			if (r == H)
				continue;

			// ๋ฐฐ์—ด์˜ ์ƒํƒœ๋ฅผ ๋ฐฑ์—…
			copy(map, newMap);

			// ํ˜„์žฌ ๋ฒฝ๋Œ ๊ธฐ์ค€์œผ๋กœ ์ฃผ๋ณ€์˜ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋ฒฝ๋Œ ํ•จ๊ป˜ ์—ฐ์‡„ ์ฒ˜๋ฆฌ
			boom(newMap, r, c);

			// ๋ถ€์„œ์ง„ ๋ฒฝ๋Œ ์ •๋ฆฌ
			down(newMap);

			// ๋‹ค์Œ ๋ฐฐ์—ด๋กœ ์ถœ๋ฐœ
			// ์ด๋ฏธ ๋๋‚ฌ๋‹ค๋ฉด ๋’ค์— ๋Œ ํ•„์š”๊ฐ€ ์—†๋‹ค.
			if (go(count + 1, newMap)) {
				return true;
			}
		}
		// ์œ„์— ๊ตฌ๋ฌธ์—์„œ true ๊ฐ€ ์•ˆ๋‚˜์˜ค๋ฉด ๋‹ค ๋ถ€์„œ์ง€์ง€ ์•Š์•˜๋‹ค๋Š” ๋œป
		return false;

	}

	// y,x ์œ„์น˜์—์„œ ์ฃผ๋ณ€์˜ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋ฒฝ๋Œ๋„ ํ•จ๊ป˜๋ถ€์ˆ˜๋Š” ์ฒ˜๋ฆฌ
	// BFS
	static void boom(int[][] map, int r, int c) {
		// BFS
		Queue<Point> q = new LinkedList<Point>();
		// ๋ฒฝ๋Œ ํฌ๊ธฐ๊ฐ€ 2์ด์ƒ์ด๋ฉด queue์— ์‚ฝ์ž…
		if (map[r][c] > 1) {
			q.offer(new Point(r, c, map[r][c]));
		}
		map[r][c] = 0; // ์ž์‹ ์€ ์ œ๊ฑฐ ์ฒ˜๋ฆฌ -> visit ์ฒ˜๋ฆฌ๋ž‘ ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค

		while (!q.isEmpty()) {
			Point p = q.poll();

			for (int i = 0; i < 4; i++) {
				int nr = p.r, nc = p.c;

				// ๋ฒฝ๋Œ์˜ ํฌ๊ธฐ - 1๋งŒํผ ๋ฐ˜๋ณต, ๊ณ„์† ์˜†์œผ๋กœ ๊ฐ€๋Š”๊ฑฐ๋‹ค
				for (int j = 1; j < p.cnt; j++) {
					nr += dr[i];
					nc += dc[i];
					if (nr >= 0 && nr < H && nc >= 0 && nc < W) {
						if (map[nr][nc] > 1) {	// ์ฃผ๋ณ€์— ์˜ํ–ฅ์„ ์ฃผ๋Š” ๋ฒฝ๋Œ์ด๋ฉด
							q.offer(new Point(nr, nc, map[nr][nc]));
						}
						map[nr][nc] = 0;	// ๋นˆ๊ณต๊ฐ„์ด๋ฉด 0, ๋ฒฝ๋Œ์ด๋ฉด ์ œ๊ฑฐ์ฒ˜๋ฆฌ
					}
				}
			}
		}
	}

	// ๋ถ€์„œ์ง„ ๋ฒฝ๋Œ ์ •๋ฆฌ, ๋ฐ‘์œผ๋กœ ๋ณด๋‚ด๊ธฐ !! ( ๊ณต์ค‘์— ๋– ์žˆ๋Š” ๊ฒƒ๋“ค )
	static ArrayList<Integer> list = new ArrayList<Integer>();

	static void down(int[][] map) {
		// ์—ด ๊ณ ์ •
		for (int c = 0; c < W; c++) {
			// ๋งจ๋ฐ‘์นธ๋ถ€ํ„ฐ ์‹œ์ž‘
			int r = H - 1;
			while (r > 0) {
				if(map[r][c] == 0) {
					int nr = r-1;
					while(nr>0 && map[nr][c] == 0) nr--;
					
					map[r][c] = map[nr][c];
					map[nr][c] = 0;
				}
				r--;
			}
		}
	}

	// ๋‚จ์€ ๋ฒฝ๋Œ ์ˆ˜ ๊ตฌํ•˜๊ธฐ
	static int getRemain(int[][] map) {
		int count = 0;
		for (int r = 0; r < H; r++) {
			for (int c = 0; c < W; c++) {
				if (map[r][c] > 0) {
					count++;
				}
			}
		}
		return count;
	}

	// ๋ฐฐ์—ด ๋ณต์‚ฌ
	static void copy(int[][] map, int[][] newMap) {
		for (int r = 0; r < H; r++) {
			for (int c = 0; c < W; c++) {
				newMap[r][c] = map[r][c];
			}
		}
	}
}

๐Ÿค” ๋‚˜์˜ ์ƒ๊ฐ

์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๋ฌธ์ œ์ด๋‹ค.
๊ตฌ์Šฌ์„ ๋–จ์–ด๋œจ๋ ค ๋ฒฝ๋Œ์„ ๊นจ๋Š”๋ฐ ๋ฒฝ๋Œ ์•ˆ์— ์žˆ๋Š” ์ˆ˜๋งŒํผ์˜ ๋ฒ”์œ„๋กœ ์ƒํ•˜์ขŒ์šฐ ๋” ๊นจ์ง„๋‹ค๊ณ  ํ•œ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด ๊ตฌ์Šฌ์„ ๋–จ์–ด๋œจ๋ฆด ์œ„์น˜ , ๋ฒฝ๋Œ ์ˆ˜ ๋ฒ”์œ„๋งŒํผ ํญํŒŒ, ํญํŒŒ๋œ ๋นˆ์นธ ์ฑ„์šฐ๊ธฐ, ๋‚จ์€ ๋ฒฝ๋Œ ์ˆ˜ ๊ตฌํ•˜๊ธฐ ๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.
๊ตฌ์Šฌ์„ ๋–จ์–ด๋œจ๋ฆด ์œ„์น˜๋Š” ์ค‘๋ณต์ˆœ์—ด์„ ์ด์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•˜๊ณ 
๋ฒฝ๋Œ ์ˆ˜ ๋งŒํผ ํญํŒŒํ•˜๋Š” ๊ณผ์ •์€ BFS๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๊ตฌ์Šฌ์„ ๊ฐ™์€ ์œ„์น˜์— ๊ณ„์† ๋†“์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
๊ทธ๋ฆฌ๊ณ  ํญํŒŒ๋œ ๋’ค 0์ด ๋œ ๋ฒฝ๋Œ๋“ค์€ ์—†์–ด์ง€๋ฏ€๋กœ ๊ทธ ๋นˆ์นธ์„ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด ํ–‰์˜ ๋งจ ๋ฐ‘๋ถ€ํ„ฐ ์œ„๋กœ ์˜ฌ๋ผ์˜ค๋ฉด์„œ ์ฒดํฌ๋ฅผ ํ•˜๊ณ  ์ˆ˜๋ฅผ ๋ฐ”๊ฟ”์ค€๋‹ค.
์ด ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜์—ฌ ์ตœ๋Œ€ํ•œ ๋งŽ์€ ๋ฒฝ๋Œ์„ ์ œ๊ฑฐํ–ˆ์„ ๋•Œ ๋‚จ์€ ๋ฒฝ๋Œ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ฉด ๋œ๋‹ค.