๐Ÿ”‘ Problem Solving/๐ŸŒณ CodeTree

[JAVA] CodeTree ์ฝ”๋“œํŠธ๋ฆฌ ๋นต

snowball๐Ÿฐ 2023. 4. 6. 10:57

https://www.codetree.ai/training-field/frequent-problems/codetree-mon-bread/description?page=3&pageSize=20&username= 

 

์ฝ”๋“œํŠธ๋ฆฌ | ์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์ค€๋น„๋ฅผ ์œ„ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ •์„

๊ตญ๊ฐ€๋Œ€ํ‘œ๊ฐ€ ๋งŒ๋“  ์ฝ”๋”ฉ ๊ณต๋ถ€์˜ ๊ฐ€์ด๋“œ๋ถ ์ฝ”๋”ฉ ์™•์ดˆ๋ณด๋ถ€ํ„ฐ ๊ฟˆ์˜ ์ง์žฅ ์ฝ”ํ…Œ ํ•ฉ๊ฒฉ๊นŒ์ง€, ๊ตญ๊ฐ€๋Œ€ํ‘œ๊ฐ€ ์—„์„ ํ•œ ์ปค๋ฆฌํ˜๋Ÿผ์œผ๋กœ ์ค€๋น„ํ•ด๋ณด์„ธ์š”.

www.codetree.ai

๐Ÿ’ก ์ „ํ˜•์ ์ธ ์‹œ๋ฎฌ๋ ˆ์ด์…˜, BFS ๋ฌธ์ œ์ด๋‹ค. → DFS๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค! ๊ฐ€์žฅ ๋จผ์ € ๋„์ฐฉํ•˜๋Š” ์œ„์น˜๋ฅผ ๋ฝ‘์•„๋‚ด์•ผ ๋˜๊ธฐ ๋•Œ๋ฌธ!

 

๋ฌธ์ œ๋ฅผ ์ฝ์–ด๋ณด๋ฉด ์„ค๋ช…์ด ๊ต‰์žฅํžˆ ์นœ์ ˆํ•˜๊ฒŒ ๋˜์–ด์žˆ๋‹ค.

์œ ์˜ํ•ด์•ผํ•  ์ ์€ 1, 2, 3์˜ ์ˆœ์„œ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ง€์ผœ์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ! ํŠนํžˆ 2๋ฒˆ์„ ์กฐ์‹ฌํ•˜์ž!

์˜ˆ๋ฅผ ๋“ค์–ด M๋ฒˆ์˜ ์‚ฌ๋žŒ๊นŒ์ง€ ๋ชจ๋‘ ์ด๋™ํ•œ ๋‹ค์Œ ํŽธ์˜์ ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ด๋™ ์ค‘ 3๋ฒˆ์˜ ์‚ฌ๋žŒ์ด ํŽธ์˜์ ์— ๋„์ฐฉํ•œ๋‹ค๋ฉด ๊ทธ๋•Œ๋ถ€ํ„ฐ ํ•ด๋‹น ํŽธ์˜์ ์€ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ๋‹ค.

๊ทธ ์™ธ์—๋Š” ๋ฌธ์ œ์— ํŠน๋ณ„ํ•œ ๊ฒƒ์€ ์—†๋‹ค. ์˜ˆ์ œ๊ฐ€ 1๊ฐœ์ด๊ณ  2๋ฒˆ์— ๋Œ€ํ•œ ํŠน์ด์ ์ด ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋”ฐ๋กœ ์ƒ๊ฐํ•˜๋ฉด์„œ ํ’€์–ด์•ผํ•œ๋‹ค.

์ „์ฒด ์ฝ”๋“œ

import java.util.*;
import java.io.*;

public class Main {
	static int N, M;
	static int[][] map;
	static int[][] store;
	static boolean[][] v;
	static ArrayDeque<int[]> people;
	static int[] dx = {-1, 0, 0, 1}, dy = {0, -1, 1, 0};
    public static void main(String args[]) throws Exception{
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine(), " ");
        N = Integer.parseInt(st.nextToken());
        M = Integer.parseInt(st.nextToken());
        map = new int[N][N];
        for(int i=0; i<N; i++) {
        	st = new StringTokenizer(bf.readLine(), " ");
        	for(int j=0; j<N; j++)
        		map[i][j] = Integer.parseInt(st.nextToken());
        }
        store = new int[M][2];
        v = new boolean[N][N];
        for(int i=0; i<M; i++){
        	st = new StringTokenizer(bf.readLine(), " ");
        	store[i][0] = Integer.parseInt(st.nextToken())-1;
        	store[i][1] = Integer.parseInt(st.nextToken())-1;
        }
        people = new ArrayDeque<>();
        int cnt = 0;
        while(true) {
        	int size = people.size();
        	if(size == 0 && cnt!=0) break;
        	while(size-- > 0) {
        		int[] t = people.poll();
        		int[] add = bfs(t[0], t[1], t[2]);
        		if(add[1] == store[t[0]][0] && add[2] == store[t[0]][1]) // ํŽธ์˜์  ๋„์ฐฉ
        			v[add[1]][add[2]] = true;
        		else people.offer(add);
        	}
        	if(cnt < M)
        		people.offer(find_basecamp(cnt, store[cnt][0], store[cnt][1]));
        	cnt++;
        }
        System.out.println(cnt);
    }
    static int[] bfs(int n, int x, int y) {
    	ArrayDeque<int[]> q = new ArrayDeque<>();
    	q.offer(new int[] {x, y, -1, -1});
    	boolean[][] visited = new boolean[N][N];
    	visited[x][y] = true;
    	while(!q.isEmpty()) {
    		int[] now = q.poll();
    		if(now[0] == store[n][0] && now[1] == store[n][1]) {
    			return new int[] {n, now[2], now[3]};
    		}
    		for(int d=0; d<4; d++) {
    			int nx = now[0] + dx[d];
    			int ny = now[1] + dy[d];
    			if(nx < 0 || ny < 0 || nx >= N || ny >= N || visited[nx][ny] || v[nx][ny]) continue;
    			visited[nx][ny] = true;
    			if(now[2] == -1) {
    				q.offer(new int[] {nx, ny, nx, ny});
    			}
    			else
    				q.offer(new int[] {nx, ny, now[2], now[3]});
    		}
     	}
    	return null; // number+์ด๋™ํ•œ ๊ณณ์˜ ์ขŒํ‘œ๋ฅผ ๋ฆฌํ„ด!
    }
    static int[] find_basecamp(int n, int x, int y) { // @param : ํŽธ์˜์ ์˜ ์œ„์น˜ - ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด base camp ์ฐพ๊ธฐ
//    	System.out.println(x+", "+y);
    	ArrayDeque<int[]> q = new ArrayDeque<>();
    	q.offer(new int[] {x, y});
    	boolean[][] visited = new boolean[N][N];
    	visited[x][y] = true;
    	while(!q.isEmpty()) {
    		int[] now = q.poll();
    		
    		if(map[now[0]][now[1]] == 1) {
    			v[now[0]][now[1]] = true;
    			return new int[] {n, now[0], now[1]};
    		}
    		for(int d=0; d<4; d++) {
    			int nx = now[0] + dx[d];
    			int ny = now[1] + dy[d];
    			if(nx < 0 || ny < 0 || nx >= N || ny >= N || visited[nx][ny] || v[nx][ny]) continue;
    			visited[nx][ny] = true;
    			q.offer(new int[] {nx, ny});
    		}
     	}
    	return null; // number+ํ•ด๋‹น ๋ฒ ์ด์Šค์บ ํ”„์˜ ์ขŒํ‘œ๋ฅผ ๋ฆฌํ„ด!
    }
}

ํ•œ ์ค„ ์”ฉ ์‚ดํŽด๋ณด์ž!

static int N, M;
static int[][] map;
static int[][] store;
static boolean[][] v;
static ArrayDeque<int[]> people;
static int[] dx = {-1, 0, 0, 1}, dy = {0, -1, 1, 0};

N, M → ์ฃผ์–ด์ง„ ๊ฐ’

map → ์ฃผ์–ด์ง„ ์ง€๋„ ์ •๋ณด

store → ํŽธ์˜์  ์ •๋ณด (์ฆ‰, store[0][0] : 1๋ฒˆ ์‚ฌ๋žŒ์ด ๊ฐˆ ํŽธ์˜์  x์ขŒํ‘œ)

v → ํŽธ์˜์ , ๋ฒ ์ด์Šค ์บ ํ”„์˜ ์ ‘๊ทผ ์—ฌ๋ถ€ ๋‚˜ํƒ€๋ƒ„

people → ์‚ฌ๋žŒ๋“ค์˜ ํ˜„์žฌ ์œ„์น˜๋ฅผ ์ €์žฅ

int cnt = 0;
while(true) {
	int size = people.size();
	if(size == 0 && cnt!=0) break;
	while(size-- > 0) {
		int[] t = people.poll();
		int[] add = bfs(t[0], t[1], t[2]);
		if(add[1] == store[t[0]][0] && add[2] == store[t[0]][1]) // ํŽธ์˜์  ๋„์ฐฉ
			v[add[1]][add[2]] = true;
		else people.offer(add);
	}
	if(cnt < M)
		people.offer(find_basecamp(cnt, store[cnt][0], store[cnt][1]));
	cnt++;
}

๋ชจ๋‘ ๋„์ฐฉํ•˜์ง€ ๋ชปํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์ฃผ์–ด์ง€์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ while์„ true๋กœ ๋‘”๋‹ค.

์ด๋•Œ ์กฐ์‚ฌํ•  ์‚ฌ๋žŒ์ด 0๋ช…์ด๋ผ๋ฉด while์„ breakํ•˜๋Š”๋ฐ ์ฒ˜์Œ ์‹œ์ž‘ํ•  ๊ฒฝ์šฐ ๋‹น์—ฐํžˆ 0๋ช…์ด๋ฏ€๋กœ cnt๊ฐ€ 0์ผ๋•Œ๋Š” ์ œ์™ธํ•œ๋‹ค.

while๋ฌธ์„ ํ†ตํ•ด ํ•œ ์‚ฌ๋žŒ์˜ ์ •๋ณด๋ฅผ ๋ฐ›์•„์„œ bfsํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋‹ค์Œ ์œ„์น˜๋ฅผ ์กฐ์‚ฌํ•˜์—ฌ add ๋ฐฐ์—ด์— ๋„ฃ์–ด์ค€๋‹ค. ์ด๋•Œ ์›ํ•˜๋Š” ํŽธ์˜์ ์— ๋„์ฐฉํ–ˆ๋‹ค๋ฉด v๋ฅผ true๋กœ ํ•˜์—ฌ ํ•ด๋‹น ์œ„์น˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†๊ฒŒ ํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  deque์— ๋‹ค์‹œ ๋„ฃ์ง€ ์•Š๋Š”๋‹ค

ํŽธ์˜์ ์— ๋„์ฐฉํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋‹ค์‹œ deque์— ๋„ฃ์–ด์ค€๋‹ค.

์ƒˆ๋กœ์šด ์‚ฌ๋žŒ์ด ์ถœ๋ฐœํ•˜๋Š” ์‹œ๊ฐ„์„ ๋ณด๊ณ  find_basecampํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋“ค์–ด๊ฐˆ ๋ฒ ์ด์Šค์บ ํ”„๋ฅผ ๊ณจ๋ผ์ค€๋‹ค.

static int[] bfs(int n, int x, int y) {
	ArrayDeque<int[]> q = new ArrayDeque<>();
	q.offer(new int[] {x, y, -1, -1});
	boolean[][] visited = new boolean[N][N];
	visited[x][y] = true;
	while(!q.isEmpty()) {
		int[] now = q.poll();
		if(now[0] == store[n][0] && now[1] == store[n][1]) {
			return new int[] {n, now[2], now[3]};
		}
		for(int d=0; d<4; d++) {
			int nx = now[0] + dx[d];
			int ny = now[1] + dy[d];
			if(nx < 0 || ny < 0 || nx >= N || ny >= N || visited[nx][ny] || v[nx][ny]) continue;
			visited[nx][ny] = true;
			if(now[2] == -1) {
				q.offer(new int[] {nx, ny, nx, ny});
			}
			else
				q.offer(new int[] {nx, ny, now[2], now[3]});
		}
 	}

ํ˜„์žฌ ์œ„์น˜๋ฅผ ๋ฐ›์•„์„œ ๋‹ค์Œ ์ด๋™ํ•  ์œ„์น˜๋ฅผ ๋ฐฐ์—ด๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

now[2], now[3]์— ์‹œ์ž‘ ์œ„์น˜๋ฅผ ๋„ฃ์–ด์ฃผ์–ด ๋งˆ์ง€๋ง‰์—๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•œ๋‹ค. → ์ด์™ธ์—๋Š” ํ‰์†Œ์˜ bfs์™€ ๋™์ผํ•˜๋‹ค.

4๋ฐฉ ํƒ์ƒ‰์„ ํ†ตํ•ด์„œ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ณณ์€ ์ œ์™ธํ•˜๊ณ  q์— ๊ฐฑ์‹ ๋œ ๊ฐ’์„ ๋„ฃ์–ด ์ด๋™ํ•œ๋‹ค.

static int[] find_basecamp(int n, int x, int y) { // @param : ํŽธ์˜์ ์˜ ์œ„์น˜ - ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด base camp ์ฐพ๊ธฐ
	ArrayDeque<int[]> q = new ArrayDeque<>();
	q.offer(new int[] {x, y});
	boolean[][] visited = new boolean[N][N];
	visited[x][y] = true;
	while(!q.isEmpty()) {
		int[] now = q.poll();
		
		if(map[now[0]][now[1]] == 1) {
			v[now[0]][now[1]] = true;
			return new int[] {n, now[0], now[1]};
		}
		for(int d=0; d<4; d++) {
			int nx = now[0] + dx[d];
			int ny = now[1] + dy[d];
			if(nx < 0 || ny < 0 || nx >= N || ny >= N || visited[nx][ny] || v[nx][ny]) continue;
			visited[nx][ny] = true;
			q.offer(new int[] {nx, ny});
		}
 	}
	return null; // number+ํ•ด๋‹น ๋ฒ ์ด์Šค์บ ํ”„์˜ ์ขŒํ‘œ๋ฅผ ๋ฆฌํ„ด!
}

ํŽธ์˜์ ์— ์œ„์น˜๋ฅผ ๋ฐ›์•„์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋ฒ ์ด์Šค์บ ํ”„์˜ ์ขŒํ‘œ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

ํŠน๋ณ„ํ•  ๊ฒƒ ์—†๋Š” bfs์ด๋‹ค. ์ด๋•Œ๋„ ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ํŽธ์˜์ ๊ณผ ๋ฒ ์ด์Šค์บ ํ”„๋กœ ์ ‘๊ทผํ•˜๋Š” ๊ฒƒ์€ ๋ถˆ๊ฐ€๋Šฅ ํ•จ์„ ์œ ์˜ํ•˜์ž