본문 바로가기
Problem Solving/백준

백준 17244 : 아맞다우산

by Libi 2021. 8. 11.
반응형

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

 

17244번: 아맞다우산

경재씨는 저녁 약속을 가기 전 챙기지 않은 물건들이 있는 지 확인하고 있다. 필요한 물건은 전부 챙긴 것 같았고 외출 후 돌아오는 길에 경재씨는 외쳤다. "아 맞다 우산!!!" 경재 씨는 매번 외출

www.acmicpc.net

[ 문제풀이 ]

전형적인 bfs + 비트마스킹 문제로 챙긴 물건의 상태를 표현하여 중복방문을 체크해주면서 목적지까지 도달하면 되는 문제이다.

물건이 최대 5개이고 맵이 최대 50x50이기 때문에 비트마스킹을 모른다고 하여도 물건을 차례대로 선택하는 모든 경우의 수를 탐색해도 통과될 것 같긴 하다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.StringTokenizer;

public class Main {

	static class Node {
		int y, x, state, time;

		public Node(int y, int x, int state, int time) {
			this.y = y;
			this.x = x;
			this.state = state;
			this.time = time;
		}
	}
	
	static int N, M, sy, sx, Xs, size;
	static char[][] map;
	static boolean[][][] visit;
	static Map<Integer, Integer> hm;
	
	static int[][] dir = {{-1,0},{1,0},{0,1},{0,-1}};
	
  	public static void main(String[] args) {
		try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
				BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out))) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			N = Integer.parseInt(st.nextToken());
			M = Integer.parseInt(st.nextToken());
			hm = new HashMap<>();
			map = new char[M][N];
			for (int i = 0; i < M; ++i) {
				String input = br.readLine();
				for (int j = 0; j < N; ++j) {
					map[i][j] = input.charAt(j);
					if (map[i][j] == 'S') {
						sy = i; sx = j;
					}
					if (map[i][j] == 'X') {
						hm.put(i * 10 + j, Xs++);
					}
				}
			}
			
			size = 1 << Xs;
			visit = new boolean[size][M][N];
			bw.write(bfs() + "\n");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
  	
  	public static int bfs() {
  		Queue<Node> q = new LinkedList<>();
  		q.offer(new Node(sy, sx, 0, 0));
  		visit[0][sy][sx] = true;
  		
  		while (!q.isEmpty()) {
  			Node n = q.poll();
  			
  			if (map[n.y][n.x] == 'E' && n.state == size - 1) {
  				return n.time;
  			}
  			
  			for (int d = 0; d < 4; ++d) {
  				int ny = n.y + dir[d][0];
  				int nx = n.x + dir[d][1];
  				
  				if (ny < 0 || nx < 0 || ny >= M || nx >= N) continue;
  				if (map[ny][nx] == '#' || visit[n.state][ny][nx]) continue;
  				
  				visit[n.state][ny][nx] = true;
  				if (map[ny][nx] == 'X') {
  					int idx = hm.get(ny * 10 + nx);
  					q.offer(new Node(ny, nx, n.state | (1 << idx), n.time + 1));
  					continue;
  				}
  				q.offer(new Node(ny, nx, n.state, n.time + 1));
  			}
  		}
  		return -1;
  	}
}

 

 

반응형

'Problem Solving > 백준' 카테고리의 다른 글

백준 1275 : 커피숍2  (1) 2021.08.14
백준 1300 : K번째 수  (0) 2021.08.12
백준 7453 : 합이 0인 네 정수  (0) 2021.08.10
백준 16434 : 드래곤 앤 던전  (0) 2021.08.09
백준 1484 : 다이어트  (0) 2021.08.08

댓글