일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- Flutter
- php 프로그래밍 입문
- C언어
- 배열
- C
- 파이썬
- JAVA SPRING
- 스프링
- 페이코 친구코드
- spring
- Java
- 페이코 추천인
- php 프로그래밍
- php
- php 프로그래밍 입문 예제
- php 프로그래밍 입문 3판
- 플러터
- 자바
- php 프로그래밍 입문 문제풀이
- 한정 분기
- 플러터 개발환경 설정
- 페이코 초대코드
- php 프로그래밍 입문 솔루션
- 자바 스프링
- 최단 경로
- 페이코 추천인코드
- programmers
- php 프로그래밍 입문 연습문제
- SWEA
- 백준
Archives
- Today
- Total
ImJay
[BOJ/Java] 3197. 백조의 호수 본문
반응형
[BOJ/Java] 3197. 백조의 호수
https://www.acmicpc.net/problem/3197
문제 해석
백조의 호수 문제는 두 마리의 백조가 있는 호수에서 얼음이 녹아 백조들이 만날 수 있는 최소 시간을 구하는 문제이다. 호수는 2차원 격자로 표현되며, 각 칸은 물('.') 또는 얼음('X')으로 구성된다. 백조는 물 위에서만 이동할 수 있으며, 매일 얼음이 물과 인접한 부분부터 녹는다. 두 백조가 만날 수 있는 최소 일수를 계산해야 한다.
풀이 과정
- 초기 설정: 호수의 상태를 입력받고, 두 백조의 위치를 찾는다. 또한, 얼음이 녹는 과정을 시뮬레이션하기 위해 BFS를 사용한다.
- 얼음 녹이기: 물과 인접한 얼음을 녹이는 과정을 BFS로 구현한다. 이때, 얼음이 녹는 순서를 큐에 저장하여 매일 얼음이 녹는 과정을 시뮬레이션한다.
- 백조 만남 확인: 두 백조가 같은 물 영역에 속하는지 확인하기 위해 BFS를 사용한다. 매일 얼음이 녹은 후, 두 백조가 연결되는지 확인한다.
- 최소 일수 계산: 얼음이 녹는 과정과 백조의 연결 여부를 반복하여 두 백조가 만나는 최소 일수를 계산한다.
코드
import java.io.*;
import java.util.*;
public class Main {
static int R, C;
static char[][] map;
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
static Queue<int[]> waterQueue = new LinkedList<>(); // 제네릭 타입 명시
static Queue<int[]> swanQueue = new LinkedList<>(); // 제네릭 타입 명시
static boolean[][] visited;
static int[] swanPos = new int[4]; // 두 백조의 위치 저장
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];
visited = new boolean[R][C];
int swanIdx = 0;
for (int i = 0; i < R; i++) {
String line = br.readLine();
for (int j = 0; j < C; j++) {
map[i][j] = line.charAt(j);
if (map[i][j] == 'L') {
swanPos[swanIdx++] = i;
swanPos[swanIdx++] = j;
}
if (map[i][j] == '.' || map[i][j] == 'L') {
waterQueue.add(new int[]{i, j});
}
}
}
// 백조의 시작 위치 설정
swanQueue.add(new int[]{swanPos[0], swanPos[1]});
visited[swanPos[0]][swanPos[1]] = true;
int day = 0;
while (true) {
if (canMeet()) {
System.out.println(day);
break;
}
meltIce();
day++;
}
}
// 백조가 만날 수 있는지 확인
static boolean canMeet() {
Queue<int[]> nextQueue = new LinkedList<>(); // 제네릭 타입 명시
while (!swanQueue.isEmpty()) {
int[] current = swanQueue.poll(); // 이제 int[]로 캐스팅됨
for (int i = 0; i < 4; i++) {
int nx = current[0] + dx[i];
int ny = current[1] + dy[i];
if (nx >= 0 && nx < R && ny >= 0 && ny < C && !visited[nx][ny]) {
if (nx == swanPos[2] && ny == swanPos[3]) {
return true;
}
if (map[nx][ny] == '.') {
visited[nx][ny] = true;
swanQueue.add(new int[]{nx, ny});
} else if (map[nx][ny] == 'X') {
visited[nx][ny] = true;
nextQueue.add(new int[]{nx, ny});
}
}
}
}
swanQueue = nextQueue;
return false;
}
// 얼음 녹이기
static void meltIce() {
int size = waterQueue.size();
for (int i = 0; i < size; i++) {
int[] current = waterQueue.poll(); // 이제 int[]로 캐스팅됨
for (int j = 0; j < 4; j++) {
int nx = current[0] + dx[j];
int ny = current[1] + dy[j];
if (nx >= 0 && nx < R && ny >= 0 && ny < C && map[nx][ny] == 'X') {
map[nx][ny] = '.';
waterQueue.add(new int[]{nx, ny});
}
}
}
}
}
시간 복잡도 분석
시간 복잡도는 O(R * C)이다. 호수의 모든 칸을 탐색하며 얼음을 녹이고, 백조가 만날 수 있는지 확인하는 과정이 각각 BFS로 구현되기 때문이다. 이는 문제의 제약 조건 내에서 효율적으로 동작한다.
느낀점
이 문제는 BFS를 활용하여 얼음이 녹는 과정과 백조의 이동을 동시에 시뮬레이션하는 문제이다. 얼음이 녹는 과정을 효율적으로 처리하기 위해 큐를 사용한 점이 핵심이었다. 또한, 백조가 만날 수 있는지 확인하는 과정에서도 BFS를 사용하여 문제를 해결할 수 있었다. 그래프 탐색과 시뮬레이션을 결합한 문제로, 실시간으로 변화하는 환경을 다루는 능력을 키울 수 있는 좋은 문제였다.
반응형
'알고리즘 > BOJ - Java' 카테고리의 다른 글
[BOJ/Java] 1655. 가운데를 말해요 (0) | 2025.03.08 |
---|---|
[BOJ/Java] 12865. 평범한 배낭 (0) | 2025.03.08 |
[BOJ/Java] 1005. ACM Craft (0) | 2025.03.08 |
[BOJ/Java] 2531. 회전 초밥 (2) | 2024.05.05 |
[BOJ/Java] 2565. 전깃줄 (0) | 2024.05.03 |
Comments