티스토리 뷰
출저 : https://www.acmicpc.net/problem/3197
"이분탐색, 맵 재정의"
문제는 이분 탐색을 통해서도 풀 수 있고, 우선순위 큐를 통해서도 풀 수 있다. 더 나아가.. union find ? 를 통해서도 풀 수 있다는데 잘 모르
겠다. 이번 풀이에서는 우선순위 큐를 사용해서 풀도록 한다.
사실 더 좋은 풀이가... 있는 것 같긴 하다 ㅠ 메모리 소요와 시간 초과가 너무 크다. 몇일 고생하다가 푼 문제라... 어쨌든 풀리긴 풀려서 다행.
그럼 풀이를 하면 가장 먼저 맵을 재정의 해야 한다. char[][] map 이외에 int[][] 형 맵을 별도로 두어 각 빙판이 몇일 째에 사라지는지를 마킹
한다. 그렇게 한 후, 이분 탐색을 한다면 빙판을 다 녹여보아서 end 값을 구하고, 구해지는 각 mid 값을 가지고 빙판을 탐색한다.
우선순위 큐를 사용한다고 하면, 맵을 재정의 한 후에 start 백조에서 end 백조까지 그냥 BFS 돌리면 된다. 우선순위 기준은 내가 지나온 빙판
위 숫자의 최대값 기준이다. 어렵다 ㅠㅠ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.PriorityQueue; import java.util.Queue; import java.util.StringTokenizer; class Main { static int R,C; static char[][] map; static int[][] water; static boolean[][] visited; static PriorityQueue<Node> q = new PriorityQueue<>(); static Queue<Node> tq = new LinkedList<>(); static int sx,sy,ex,ey; static int idx; static int[] dx = {0,0,1,-1}; static int[] dy = {1,-1,0,0}; public static void main (String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); R = Integer.parseInt(st.nextToken()); C = Integer.parseInt(st.nextToken()); map = new char[R][C]; water = new int[R][C]; int idx = 0; for (int i = 0; i < R; i++) { char[] temp = br.readLine().toCharArray(); for (int j = 0; j < C; j++) { map[i][j] = temp[j]; if(temp[j] == 'L') { map[i][j] = '.'; if(idx ++ == 0) { sx = i; sy = j; } else { ex = i; ey = j; } } } } mark(); System.out.println(solve()); } static int solve() { visited = new boolean[R][C]; visited[sx][sy] = true; q.add(new Node(sx, sy, 0)); while(!q.isEmpty()) { Node cur = q.poll(); if(cur.x == ex && cur.y == ey ) { return cur.day; } for (int i = 0; i < 4; i++) { int nx = cur.x + dx[i]; int ny = cur.y + dy[i]; if(!isRange(nx, ny) || visited[nx][ny]) continue; visited[nx][ny] = true; q.add(new Node(nx, ny, Math.max(cur.day, water[nx][ny]))); } } return 0; } static void mark() { visited = new boolean[R][C]; int day = 0; for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { if(map[i][j] == '.') { visited[i][j] = true; tq.add(new Node(i, j, 0)); } } } while(!tq.isEmpty()) { int size = tq.size(); for (int s = 0; s < size; s++) { Node cur = tq.poll(); water[cur.x][cur.y] = day; for (int k = 0; k < 4; k++) { int nx = cur.x + dx[k]; int ny = cur.y + dy[k]; if(!isRange(nx, ny) || visited[nx][ny]) continue; visited[nx][ny] = true; tq.add(new Node(nx, ny,0)); } } day++; } } static boolean isRange(int x, int y) { if( x < 0 || x >= R || y < 0 || y >= C) return false; return true; } } class Node implements Comparable<Node> { int x; int y; int day; Node( int x, int y, int day) { this.x = x; this.y = y; this.day = day; } @Override public int compareTo(Node o) { return this.day - o.day; } } | cs |
'Study > 알고리즘 문제풀이' 카테고리의 다른 글
백준 2980. 도로와 신호등 :: 돼지개발자 (0) | 2018.11.15 |
---|---|
백준 3985. 롤 케이크 :: 돼지개발자 (0) | 2018.11.15 |
SWEA 5656. [모의 SW 역량테스트] 벽돌깨기 :: 돼지개발자 (0) | 2018.11.13 |
백준 2151. 거울 설치 :: 돼지개발자 (0) | 2018.11.11 |
백준 3108. 로고 :: 돼지개발자 (1) | 2018.11.09 |
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday