문제 풀이: BFS를 사용한 조각 구성
우선 석유가 위치한 땅을 조각(Fragment)으로 구성합니다. Fragment는 BFS를 사용하여 계산 할 수 있습니다.
- 각 Fragment는
ID를 갖습니다. 좌표 x, y를 사용해Fragment ID를 구할 수 있습니다.Fragment ID를 사용해Fragment의 크기를 구할 수 있습니다.
위 좌표계는 Frament ID를 표현하는 이중 배열 샘플입니다.
석유 시추는 특정 열에 대해서 진행됩니다. 모든 x 좌표에 대해서 각 열이 갖는 Fragment의 크기를 합산하면 결과를 구할 수 있습니다.
이때 하나의 열에서 Fragment ID가 중복되지 않도록 합니다(동일한 Fragment가 합산되지 않도록).
문제를 풀기 위해 BFS를 구현하는 함수를 작성합니다. 이 함수에서는 Fragment ID와 Fragment 크기를 계산합니다.
public void bfs(int[][] land, int x, int y)
{
Queue<int[]> queue = new LinkedList<>();
visited[y][x] = true;
fragmentIds[y][x] = fragmentId;
queue.add(new int[] { x, y } );
int fragmentSize = 0;
while (!queue.isEmpty())
{
int[] cur = queue.poll();
++fragmentSize;
for (int i = 0; i < 4; ++i)
{
int cx = cur[0] + dw[i];
int cy = cur[1] + dy[i];
if (0 > cx || 0 > cy || w <= cx || h <= cy || true == visited[cy][cx] || 0 == land[cy][cx])
continue;
visited[cy][cx] = true;
fragmentIds[cy][cx] = fragmentId;
queue.add(new int[] { cx, cy });
}
}
fragmentSizes.put(fragmentId++, fragmentSize);
}
코드 | 비고 | |
현재 |
||
현재 |
||
현재 방문을 |
||
마지막 방문 좌표를 기준으로 검사된 좌표에 |
||
각 좌표 별로 Fragment ID와 Fragment 크기를 알고 있으면 문제를 해결 할 수 있습니다.
각 열에 대한 Fragment 크기의 합을 계산합니다. 전체 코드는 다음과 같습니다.
package com.example.test;
import java.util.*;
class Solution
{
static int w, h;
static boolean visited[][];
static Map<Integer, Integer> fragmentSizes = new HashMap<>();
static int fragmentIds[][];
static int fragmentId = 1;
static int[] dw = { 0, 1, 0, -1 };
static int[] dy = { 1, 0, -1, 0 };
public void bfs(int[][] land, int x, int y)
{
Queue<int[]> queue = new LinkedList<>();
visited[y][x] = true;
fragmentIds[y][x] = fragmentId;
queue.add(new int[] { x, y } );
int fragmentSize = 0;
while (!queue.isEmpty())
{
int[] cur = queue.poll();
++fragmentSize;
for (int i = 0; i < 4; ++i)
{
int cx = cur[0] + dw[i];
int cy = cur[1] + dy[i];
if (0 > cx || 0 > cy || w <= cx || h <= cy || true == visited[cy][cx] || 0 == land[cy][cx])
continue;
visited[cy][cx] = true;
fragmentIds[cy][cx] = fragmentId;
queue.add(new int[] { cx, cy });
}
}
fragmentSizes.put(fragmentId++, fragmentSize);
}
public int solution(int[][] land) {
w = land[0].length;
h = land.length;
visited = new boolean[h][w];
fragmentIds = new int[h][w];
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (true == visited[y][x] || 0 == land[y][x])
continue;
bfs(land, x, y);
}
}
int answer = 0;
for (int x = 0; x < w; ++x) {
Set<Integer> founds = new HashSet<>();
for (int y = 0; y < h; ++y) {
if (0 < fragmentIds[y][x]) {
founds.add(fragmentIds[y][x]);
}
}
int sum = 0;
for (int fragmentId : founds) {
sum += fragmentSizes.get(fragmentId);
}
if (answer < sum)
answer = sum;
}
return answer;
}
}
'Algorithm > Programmers' 카테고리의 다른 글
Level 1: 카드 뭉치, 배열의 큐잉(Queueing) (0) | 2023.12.06 |
---|---|
Level 2: 광물 캐기, 그리디 알고리즘 (0) | 2023.12.05 |
Level 1: PCCP 기출 문제 - 데이터 분석, Stream 필터와 정렬 (0) | 2023.12.04 |
Level 1: PCCP 기출문제 - 이웃한 칸, 이중 배열의 랜덤 엑세스 (0) | 2023.12.04 |
Level 1: PCCP 기출문제 - 붕대 감기, 시간 경과에 따른 로직 계산 (0) | 2023.12.04 |