1. 문제
https://www.acmicpc.net/problem/3197
3197번: 백조의 호수
입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500. 다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.
www.acmicpc.net
2. 접근방법
1. 각 빙판이 녹는데 필요한 시간들을 탐색 후 배열에 저장
2. 백조 한마리부터 bfs를 돌며 다른 백조를 찾을 때까지 탐색
2-1. bfs를 돌며 빙판을 지나갈 때는 그 빙판이 녹는 day와 지금껏 지나온 빙판의 day중 더 큰 것 저장.
2-2. PriorityQue를 이용해 저장한 day가 가장 작은 것부터 탐색.
3. 다른 백조를 만나면 바로 종료 후 저장 된 day 출력
4. 끝.
3. 자바 코드
package Gold;
import java.awt.Point;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.StringTokenizer;
public class G1_3197백조의호수 {
static char[][] map;
static int[][] dayMap;
static int R, C;
static Queue<Point> water = new LinkedList<Point>();
static Point bird1, bird2;
static class node implements Comparable<node> {
int x;
int y;
int day;
public 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;
}
}
public static void main(String[] args) throws Exception {
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];
dayMap = new int[R][C];
for (int i = 0; i < R; i++) {
map[i] = br.readLine().toCharArray();
for (int j = 0; j < C; j++) {
if (map[i][j] != 'X')
water.add(new Point(i, j));
if (map[i][j] == 'L')
if (bird1 == null)
bird1 = new Point(i, j);
else
bird2 = new Point(i, j);
}
}
dayday();
System.out.println(find());
}
static int dr[] = { 1, -1, 0, 0 };
static int dc[] = { 0, 0, 1, -1 };
static void dayday() {
int day = 0;
while (!water.isEmpty()) {
int size = water.size();
day++;
for (int s = 0; s < size; s++) {
Point now = water.poll();
for (int i = 0; i < 4; i++) {
int row = now.x + dr[i];
int col = now.y + dc[i];
if (row < 0 || col < 0 || row >= R || col >= C)
continue;
if (map[row][col] != 'X')
continue;
dayMap[row][col] = day;
map[row][col] = '.';
water.add(new Point(row, col));
}
}
}
}
static int find() {
PriorityQueue<node> pq = new PriorityQueue<node>();
boolean visit[][] = new boolean[R][C];
pq.add(new node(bird1.x, bird1.y, 0));
while (!pq.isEmpty()) {
node now = pq.poll();
if(now.x == bird2.x && now.y == bird2.y)
return now.day;
for (int i = 0; i < 4; i++) {
int row = now.x + dr[i];
int col = now.y + dc[i];
if (row < 0 || col < 0 || row >= R || col >= C)
continue;
if (visit[row][col])
continue;
visit[row][col] = true;
pq.add(new node(row, col, Math.max(now.day, dayMap[row][col])));
}
}
return 0;
}
}
4. 마치며
7개월전에 풀었다가 시간초과나고 안풀었는데
그 때 어떻게 풀었는지는 기억안나지만 이번엔 한번에 풀어냈다 ㅎㅎ
'알고리즘 문제풀이 > 백준' 카테고리의 다른 글
[백준] 2075 N번째 큰수 (0) | 2021.10.01 |
---|---|
[백준] 7662 이중 우선순위 큐 (1) | 2021.09.30 |
[백준] 1167 트리의 지름 (2) | 2021.08.22 |
[백준] 19236 청소년 상어 (0) | 2021.06.21 |
[백준] 20061 모노미노도미노2 (0) | 2021.06.21 |