λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
2️⃣ Java/Problem Solving

[Java Algorithm] λ²½ λΆ€μˆ˜κ³  μ΄λ™ν•˜κΈ° BOJ #2206

by seolhee2750 2022. 8. 8.
문제

https://www.acmicpc.net/problem/2206

 

2206번: λ²½ λΆ€μˆ˜κ³  μ΄λ™ν•˜κΈ°

N×M의 ν–‰λ ¬λ‘œ ν‘œν˜„λ˜λŠ” 맡이 μžˆλ‹€. λ§΅μ—μ„œ 0은 이동할 수 μžˆλŠ” 곳을 λ‚˜νƒ€λ‚΄κ³ , 1은 이동할 수 μ—†λŠ” 벽이 μžˆλŠ” 곳을 λ‚˜νƒ€λ‚Έλ‹€. 당신은 (1, 1)μ—μ„œ (N, M)의 μœ„μΉ˜κΉŒμ§€ μ΄λ™ν•˜λ € ν•˜λŠ”λ°, μ΄λ•Œ μ΅œλ‹¨ 경둜

www.acmicpc.net

 

λ‚΄ 문제 풀이
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.StringTokenizer;

public class Main {
	static int[] dx = {0, 0 ,-1, 1};
	static int[] dy = {-1, 1, 0, 0};
	static Deque<int[]> que;
	static char[][] map;
	static int n;
	static int m;
	static int[][][] visited; // μžλ¦¬λ§ˆλ‹€ 벽을 λΆ€μˆ˜κ³  μ™”λŠ”μ§€, μ•ˆλΆ€μˆ˜κ³  μ™”λŠ”μ§€λ₯Ό μ €μž₯
	
	public static int bfs() {
		while(!que.isEmpty()) {
			int[] now = que.removeFirst();
			int x = now[0];
			int y = now[1];
			int z = now[2];
			
			if(x == n-1 && y == m-1) return visited[x][y][z];
			
			for(int i = 0; i < 4; i++) {
				int nx = x + dx[i];
				int ny = y + dy[i];
				
				if(nx < 0 || ny < 0 || nx >= n || ny >= m) continue;
				
				if(visited[nx][ny][z] == 0) {
					// 벽이 μžˆλŠ”λ°, μ΄μ „κΉŒμ§€λŠ” 벽을 λΆ€μˆ˜μ§€ μ•Šμ•˜λ˜ 경우 (== λΆ€μˆ  수 μžˆλŠ” 경우)
					if(map[nx][ny] == '1' && z == 1) {
						visited[nx][ny][0] = visited[x][y][1] + 1;
						que.add(new int[]{nx, ny, 0});
					}
					// 벽이 μ•„λ‹Œ 경우
					else if(map[nx][ny] == '0') {
						visited[nx][ny][z] = visited[x][y][z] + 1;
						que.add(new int[]{nx, ny, z});
					}
				}
			}
		}
		
		return -1;
	}

	public static void main(String[] args) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st;

		st = new StringTokenizer(in.readLine());
		n = Integer.parseInt(st.nextToken());
		m = Integer.parseInt(st.nextToken());
		map = new char[n][m];
		
		for(int i = 0; i < n; i++) {
			String tmp = in.readLine();
			for(int j = 0; j < m; j++) {
				map[i][j] = tmp.charAt(j);
			}
		}
		
		que = new ArrayDeque<>();
		que.add(new int[]{0, 0, 1}); // {xμ’Œν‘œ, yμ’Œν‘œ, 벽을 λΆ€μ‰ˆλŠ”μ§€ μ•„λ‹Œμ§€} (λΆ€μˆœ 경우 0, λΆ€μˆ˜μ§€ μ•Šμ€ 경우 1)
		visited = new int[n][m][2];
		visited[0][0][1] = 1; // [][][0]은 λΆ€μˆœμ  μžˆλŠ” 경우, [][][1]은 λΆ€μˆœμ  μ—†λŠ” κ²½μš°μ— λŒ€ν•œ λˆ„μ  μ‹œκ°„μ„ μ €μž₯
		
		System.out.println(bfs());
	}

}

πŸ‘‰ BFS 문제

[ λ³€μˆ˜ μ„€λͺ… ]

  • dx, dy
    μƒν•˜μ’Œμš° 탐색을 μœ„ν•œ μ’Œν‘œ λ°°μ—΄
  • que
    bfs 탐색 쀑 μƒˆλ‘­κ²Œ 탐색할 μ’Œν‘œκ°’κ³Ό 벽을 λΆ€μ‰ˆλŠ”μ§€ μ—¬λΆ€λ₯Ό μ €μž₯ν•  덱
    (xμ’Œν‘œ, yμ’Œν‘œ, 벽을 λΆ€μˆœμ  μžˆλŠ”μ§€ μ—¬λΆ€(λΆ€μˆœμ  있으면 0, λΆ€μˆ˜μ§€ μ•Šμ•˜μœΌλ©΄ 1))
  • visited
    μž…λ ₯λ˜λŠ” 맡과 같은 크기의 배열인데, μžλ¦¬λ§ˆλ‹€ 벽을 λΆ€μˆœμ  μžˆλŠ”μ§€ μ—†λŠ”μ§€μ— λŒ€ν•œ 경우λ₯Ό
    λ‚˜λˆ μ„œ λ°©λ¬Έ 체크λ₯Ό ν•˜κΈ° μœ„ν•΄ 3차원 λ°°μ—΄λ‘œ ν™•μž₯μ‹œμΌœμ„œ λ§Œλ“€μ–΄μ£Όμ—ˆλ‹€.
    ([][][0] μžλ¦¬κ°€ 0이 μ•„λ‹ˆλ©΄ 벽을 λΆ€μˆœ 적 있고, [][][1] μžλ¦¬κ°€ 0이 μ•„λ‹ˆλ©΄ λΆ€μˆœμ  μ—†λ‹€λŠ” 뜻)

 

[ 풀이 μ„€λͺ… ]

  • bfs 탐색 μ „, 첫 번째 μžλ¦¬μ—μ„œλŠ” λ‹Ήμ—°νžˆ 벽을 λΆ€μˆ˜μ§€ μ•ŠμœΌλ―€λ‘œ que에 {0, 0, 1}을 μΆ”κ°€ν–ˆκ³ ,
    visited에도 벽을 λΆ€μˆ˜μ§€ μ•ŠλŠ” 자리인 [0][0][1]에 1을 μ €μž₯ν•΄μ£Όμ—ˆλ‹€.
  • bfs λ©”μ„œλ“œμ—μ„œλŠ” queκ°€ λΉ„μ–΄μžˆκ²Œ 되기 μ „κΉŒμ§€ while문을 λ°˜λ³΅ν•˜λ„λ‘ ν–ˆλŠ”λ°,
    λ§Œμ•½ x, yκ°€ 도착 μ§€μ μ˜ μ’Œν‘œκ°’κ³Ό 같을 μ‹œ returnν•˜λ„λ‘ ν–ˆλ‹€. (κ°€μž₯ λΉ λ₯Έ 도착)
  • 같지 μ•Šμ„ κ²½μš°μ—λŠ” for문을 μ΄μš©ν•˜μ—¬ μƒν•˜μ’Œμš°λ₯Ό νƒμƒ‰ν–ˆλ‹€.
    visited λ°°μ—΄μ˜ ν•΄λ‹Ήν•˜λŠ” μžλ¦¬μ— 1이 μ €μž₯λ˜μ–΄μžˆλ‹€λ©΄ 이미 λ°©λ¬Έν•œ μžλ¦¬λΌλŠ” λœ»μ΄λ―€λ‘œ
    λ”°λ‘œ 쑰건을 정해주지 μ•Šμ•˜κ³ , 0이 μ €μž₯된 κ²½μš°μ—λ§Œ μƒˆλ‘œμš΄ 탐색을 ν•΄μ£Όμ—ˆλ‹€.
  • λ§Œμ•½ map[nx][ny]에 1(λ²½)이 μ €μž₯λ˜μ–΄μžˆλŠ”λ°, zκ°€ 1이라면 벽을 λΆ€μˆ  수 μžˆλ‹€λŠ” λœ»μ΄λ―€λ‘œ,
    벽을 λΆ€μˆ˜κ³  λ‹€μŒ 자리둜 λ‚˜μ•„κ°ˆ 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€. λ”°λΌμ„œ μš°λ¦¬λŠ” 벽을 λΆ€μˆ  것이며,
    ν•œ 번 λΆ€μ‰ˆλ‹€λŠ” 것을 ν‘œμ‹œν•˜κΈ° μœ„ν•΄ visited[nx][ny][0]에 visited[x][y][1] + 1을 μ €μž₯ν–ˆλ‹€.
  • λ§Œμ•½ map[nx][ny]에 0이 μ €μž₯λ˜μ–΄μžˆλ‹€λ©΄ 이전에 벽을 λΆ€μ‰ˆλ“  μ•ˆλΆ€μ‰ˆλ“  (zκ°€ 0이든 1이든)
    무쑰건 λ‹€μŒ 자리둜 이동할 수 μžˆλ‹€λŠ” μ˜λ―Έμ΄λ‹€. λ”°λΌμ„œ μš°λ¦¬λŠ” λ‹€μŒμœΌλ‘œ 이동할 것이며,
    visited[nx][ny][z]에 visited[x][y][z] + 1을 μ €μž₯ν•΄μ£Όμ—ˆλ‹€.
  • while 반볡이 끝날 λ•ŒκΉŒμ§€ bfs ν•¨μˆ˜κ°€ λ¦¬ν„΄λ˜μ§€ μ•Šμ•˜λ‹€λ©΄ 도착 λΆˆκ°€λ‘œ νŒλ‹¨, -1을 λ¦¬ν„΄ν–ˆλ‹€.

 

πŸ’‘ ν”Όλ“œλ°±
  • visited λ°°μ—΄κ³Ό que μš”μ†Œμ— λŒ€ν•œ νŒλ‹¨μ΄ λ³΅μž‘ν•΄μ„œ ν—·κ°ˆλ¦¬κΈ°λ„ ν–ˆμ§€λ§Œ 어렡지 μ•Šμ€ λ¬Έμ œμ˜€λ‹€.

λŒ“κΈ€