[백준/BOJ] 9328 열쇠 - JAVA

2024. 8. 22. 22:35·알고리즘/문제풀이

백준 BOJ 9328 열쇠 - JAVA
수정중

[9328번: 열쇠

상근이는 1층 빌딩에 침입해 매우 중요한 문서를 훔쳐오려고 한다. 상근이가 가지고 있는 평면도에는 문서의 위치가 모두 나타나 있다. 빌딩의 문은 모두 잠겨있기 때문에, 문을 열려면 열쇠가

www.acmicpc.net](https://www.acmicpc.net/problem/9328)

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

class Pos {
    private int r;
    private int c;

    public Pos(int r, int c) {
        this.r = r;
        this.c = c;
    }

    public int getR() {
        return r;
    }

    public int getC() {
        return c;
    }
}

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;
        int T = Integer.parseInt(br.readLine());
        for (int tc = 0; tc < T; tc++) {
            // 입력
            st = new StringTokenizer(br.readLine());
            int h = Integer.parseInt(st.nextToken());
            int w = Integer.parseInt(st.nextToken());
            char[][] map = new char[h + 1][w + 1];

            Queue<Pos> queue = new ArrayDeque<>();
            for (int r = 1; r <= h; r++) {
                String line = br.readLine();
                for (int c = 1; c <= w; c++) {
                    map[r][c] = line.charAt(c - 1);
                    if (map[r][c] != '*') {
                        if (r == 1 || r == h || c == 1 || c == w) {
                            queue.add(new Pos(r, c));
                        }
                    }
                }
            }

            int key = 0;
            String keyList = br.readLine();
            if (!keyList.equals("0")) {
                int keyNum = keyList.length();
                for (int i = 0; i < keyNum; i++) {
                    key = key | (1 << (keyList.charAt(i) - 'a'));
                }
            }

            int answer = 0;

            // bfs
            int[][] dr = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
            Map<Character, List<Pos>> doorMap = new HashMap<>();
            boolean[][] visited = new boolean[h + 1][w + 1];
            while (!queue.isEmpty()) {
                Pos now = queue.poll();
                int nowR = now.getR();
                int nowC = now.getC();
                if (map[nowR][nowC] == '.') {
                    visited[nowR][nowC] = true;
                } else if (map[nowR][nowC] == '$') {
                    answer++;
                    visited[nowR][nowC] = true;
                    map[nowR][nowC] = '.';
                } else if (Character.isUpperCase(map[nowR][nowC])) {    // 문
                    int door = 1 << (map[nowR][nowC] - 'A');
                    if ((door & key) > 0) {   //열쇠 있음
                        visited[nowR][nowC] = true;
                        map[nowR][nowC] = '.';
                    } else {  //열쇠 없음
                        List<Pos> doorList = new ArrayList<>();
                        if (doorMap.containsKey(map[nowR][nowC])) {
                            doorList = doorMap.get(map[nowR][nowC]);
                        }
                        doorList.add(new Pos(nowR, nowC));
                        doorMap.put(map[nowR][nowC], doorList);
                        continue;
                    }
                } else {    //열쇠
                    visited[nowR][nowC] = true;
                    char matchDoor = Character.toUpperCase(map[nowR][nowC]);
                    if (doorMap.containsKey(matchDoor)) {
                        List<Pos> doorList = doorMap.get(matchDoor);
                        queue.addAll(doorList);
                        doorMap.remove(matchDoor);
                    }
                    key = key | (1 << (map[nowR][nowC] - 'a'));
                }
                for (int[] d : dr) {
                    int nextR = nowR + d[0];
                    int nextC = nowC + d[1];
                    if (nextR < 1 || nextR > h || nextC < 1 || nextC > w) {
                        continue;
                    }
                    if (map[nextR][nextC] == '*' || visited[nextR][nextC]) {
                        continue;
                    }
                    queue.add(new Pos(nextR, nextC));
                }
            }
            sb.append(answer).append("\n");
        }
        System.out.println(sb);
    }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

class Pos {
    private int r;
    private int c;

    public Pos(int r, int c) {
        this.r = r;
        this.c = c;
    }

    public int getR() {
        return r;
    }

    public int getC() {
        return c;
    }
}

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder();
        StringTokenizer st;
        int T = Integer.parseInt(br.readLine());
        for (int tc = 0; tc < T; tc++) {
            // 입력
            st = new StringTokenizer(br.readLine());
            int h = Integer.parseInt(st.nextToken());
            int w = Integer.parseInt(st.nextToken());
            char[][] map = new char[h + 1][w + 1];

            Queue<Pos> queue = new ArrayDeque<>();
            boolean[][] visited = new boolean[h + 1][w + 1];
            for (int r = 1; r <= h; r++) {
                String line = br.readLine();
                for (int c = 1; c <= w; c++) {
                    map[r][c] = line.charAt(c - 1);
                    if (map[r][c] != '*') {
                        if (r == 1 || r == h || c == 1 || c == w) {
                            queue.add(new Pos(r, c));
                            visited[r][c] = true;
                        }
                    }
                }
            }

            int key = 0;
            String keyList = br.readLine();
            if (!keyList.equals("0")) {
                int keyNum = keyList.length();
                for (int i = 0; i < keyNum; i++) {
                    key = key | (1 << (keyList.charAt(i) - 'a'));
                }
            }

            int answer = 0;

            // bfs
            int[][] dr = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
            List<Pos>[] doorArr = new List[26];
            for (int i = 0; i < 26; i++) {
                doorArr[i] = new ArrayList<>();
            }
            while (!queue.isEmpty()) {
                Pos now = queue.poll();
                int nowR = now.getR();
                int nowC = now.getC();
                if (map[nowR][nowC] == '.') {
                } else if (map[nowR][nowC] == '$') {
                    answer++;
                    map[nowR][nowC] = '.';
                } else if (map[nowR][nowC] >= 'A' && map[nowR][nowC] <= 'Z') {    // 문
                    int doorNum = map[nowR][nowC] - 'A';
                    int door = 1 << doorNum;
                    if ((door & key) > 0) {   //열쇠 있음
                        map[nowR][nowC] = '.';
                    } else {  //열쇠 없음
                        doorArr[doorNum].add(new Pos(nowR, nowC));
                        continue;
                    }
                } else {    //열쇠
                    int door = map[nowR][nowC] - 'a';
                    queue.addAll(doorArr[door]);
                    doorArr[door] = new ArrayList<>();
                    key = key | (1 << (map[nowR][nowC] - 'a'));
                }
                for (int[] d : dr) {
                    int nextR = nowR + d[0];
                    int nextC = nowC + d[1];
                    if (nextR < 1 || nextR > h || nextC < 1 || nextC > w) {
                        continue;
                    }
                    if (map[nextR][nextC] == '*' || visited[nextR][nextC]) {
                        continue;
                    }
                    queue.add(new Pos(nextR, nextC));
                    visited[nextR][nextC] = true;
                }
            }
            sb.append(answer).append("\n");
        }
        System.out.println(sb);
    }
}

수정중

728x90
저작자표시 비영리 변경금지 (새창열림)
'알고리즘/문제풀이' 카테고리의 다른 글
  • [프로그래머스] 1844 게임 맵 최단거리 - JAVA - Lv.2
  • [프로그래머스] 72413 합승 택시 요금 - JAVA - Lv.3
  • [백준/BOJ] 11053 가장 긴 증가하는 부분 수열 - JAVA
  • [백준/BOJ] 14939 불 끄기 - JAVA
LIRI
LIRI
  • LIRI
    기록
    LIRI
  • 전체
    오늘
    어제
    • 분류 전체보기 (73)
      • 블로그 꾸미기 (0)
      • Spring (6)
      • React (3)
      • CS (0)
      • 알고리즘 (57)
        • 개념 (2)
        • 문제풀이 (54)
      • Java (1)
      • DB (1)
      • log (4)
        • SSAFY (3)
        • 궁금 (1)
  • 블로그 메뉴

    • 홈
    • 방명록
  • 공지사항

  • 인기 글

  • 태그

    Java
    최장증가부분수열
    골드1
    알고리즘
    너비우선탐색
    리액트
    불 끄기
    JWT
    프로그래머스
    pccp모의고사
    BOJ
    Security
    LIS
    dp
    Spring
    비트마스킹
    SSAFY
    lv3
    BFS
    dfs
    Springsecurity
    ssafy 합격 후기
    알고리즘 문제풀이
    springboot
    그리디
    백준
    싸피
    SSAFY 9기
    LV2
    도대체왜
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.3
LIRI
[백준/BOJ] 9328 열쇠 - JAVA
상단으로

티스토리툴바