문제
세로길이가 n, 가로길이가 m인 격자 모양의 땅 속에서 석유가 발견되었습니다. 석유는 여러 덩어리로 나누어 묻혀있습니다. 당신이 시추관을 수직으로 단 하나만 뚫을 수 있을 때, 가장 많은 석유를 뽑을 수 있는 시추관의 위치를 찾으려고 합니다. 시추관은 열 하나를 관통하는 형태여야 하며, 열과 열 사이에 시추관을 뚫을 수 없습니다.

시추관은 세로로 들어온다...
뚫으면서 시추 가능한 OIL 덩어리의 최대값을 구하는 문제..
그림 예시)
1 -> 8
2 -> 8
3 -> 8
4 -> 7
5 -> 7
6 -> 7
7 -> 7 + 2 => 9
8 -> 2
접근!
덩어리마다 ID 를 부여하는 방식?

그리고 id 마다 크기를 HashMap에 저장?
<Id, Size> {1,8} , {2,7} , {3,2}
세로로 시추관 뚫으면서 oil 인 경우 Map 과 비교후 저장?
psuedo code
for 행
for 열
if 방문 x and 기름
size = bfs(Land, 행, 열, ID)
Map.put(ID++, size)
bfs 코드
bfs(Land, 행, 열, ID) {
queue 생성
q <- 행, 열
방문처리 = true
int size = 1 // 처음 크기는 1로 스타트
land_ID[][] = ID; // id 로 저장
while !q.isEmpty
for loop
동서남북 Search
if 탐색 가능하고 방문 안했고 기름이면
size++;
return size;
}
덩어리 합 구하는 코드
//세로로 탐색하기 때문에 행 열 반대로 ~
for 열 {
Set<Integer> set -> Id를 저장하는 Set
int MAX = 0;
for 행 {
if (해당 칸이 1(석유)라면 ) {
Set에 해당 좌표의 Id를 저장
}
}
for (Set의 ID) {
MAX += 오일크기를 담은 MAP.get(id)
}
answer = Math.max(maxOil, sum)
}
이 부분이 좀 헷갈렸다. 더 쉬운 방법은 없는지 계속 생각했고
결국 set을 계속 초기화 해주면서 기름을 찾으면 그에 해당하는 size 를 더해가면서 진행했다.
전체 코드
import java.util.*;
class Solution {
static int[] dx = {-1,1,0,0};
static int[] dy = {0,0,-1,1};
static int[][] landId; // 덩어리를 담을 map
static boolean[][] visited;
static int rows,cols;
static HashMap<Integer,Integer> oil_info = new HashMap<>();
public int solution(int[][] land) {
int answer = 0;
rows = land.length;
cols = land[0].length;
landId = new int[rows][cols];
visited = new boolean[rows][cols];
int oil_index = 1;
for(int i=0; i<rows; i++) {
for(int j=0;j<cols;j++){
if(!visited[i][j] && land[i][j] == 1){
//bfs 시작
int size = bfs(land,i,j,oil_index); //rows, cols
oil_info.put(oil_index++,size);
}
}
}
for(int i=0; i<cols; i++) {
HashSet<Integer> set = new HashSet<>();
int temp = 0;
for(int j=0; j<rows; j++) {
if(land[j][i] == 1) {
set.add(landId[j][i]);
}
}
for(Integer oil : set) {
temp += oil_info.get(oil);
System.out.println(temp);
}
answer = Math.max(temp,answer);
}
return answer;
}
private int bfs(int[][] land, int n, int m, int oil_index) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[] {n,m});
visited[n][m] = true;
landId[n][m] = oil_index;
int oil_size = 1;
while(!q.isEmpty()) {
int[] pos = q.poll();
for(int i=0; i<4; i++) {
int nx = pos[0] + dx[i];
int ny = pos[1] + dy[i];
if(nx >= 0 && nx < rows && ny >= 0 && ny < cols) {
if(!visited[nx][ny] && land[nx][ny] == 1) {
q.offer(new int[] {nx,ny});
landId[nx][ny] = oil_index;
visited[nx][ny] = true;
oil_size++;
}
}
}
}
return oil_size;
}
}
재밌게 풀었다. 덩어리 합 구하는 부분에서 좀 막히긴 했지만 어찌저찌 해결해 나간듯하다.
'프로그래머스' 카테고리의 다른 글
| 과제 진행하기 <JAVA> - Level2 (0) | 2024.01.28 |
|---|---|
| 2024 KAKAO WINTER INTERNSHIP - 도넛과 막대 그래프 <JAVA> (0) | 2024.01.26 |
| 2024 KAKAO WINTER INTERNSHIP - N + 1 카드게임 <JAVA> (1) | 2024.01.26 |
| 2019 KAKAO BLIND RECRUITMENT - 길 찾기 게임 <JAVA> (2) | 2024.01.24 |
| [PCCP 기출문제] 4번 / 수레 움직이기 <JAVA> (0) | 2024.01.22 |