Skip to content

Commit 90eee97

Browse files
committed
[level 2] Title: [PCCP 기출문제] 2번 / 석유 시추, Time: 68.17 ms, Memory: 74.1 MB -BaekjoonHub
1 parent 1722f42 commit 90eee97

2 files changed

Lines changed: 298 additions & 0 deletions

File tree

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
# [level 2] [PCCP 기출문제] 2번 / 석유 시추 - 250136
2+
3+
[문제 링크](https://school.programmers.co.kr/learn/courses/30/lessons/250136)
4+
5+
### 성능 요약
6+
7+
메모리: 74.1 MB, 시간: 68.17 ms
8+
9+
### 구분
10+
11+
코딩테스트 연습 > PCCP 기출문제
12+
13+
### 채점결과
14+
15+
정확성: 60.0<br/>효율성: 40.0<br/>합계: 100.0 / 100.0
16+
17+
### 제출 일자
18+
19+
2024년 11월 28일 05:22:50
20+
21+
### 문제 설명
22+
23+
<p><strong>[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]</strong></p>
24+
25+
<p>세로길이가 <code>n</code> 가로길이가 <code>m</code>인 격자 모양의 땅 속에서 석유가 발견되었습니다. 석유는 여러 덩어리로 나누어 묻혀있습니다. 당신이 시추관을 수직으로 <strong>단 하나만</strong> 뚫을 수 있을 때, 가장 많은 석유를 뽑을 수 있는 시추관의 위치를 찾으려고 합니다. 시추관은 열 하나를 관통하는 형태여야 하며, 열과 열 사이에 시추관을 뚫을 수 없습니다.</p>
26+
27+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/beb862a9-5382-4f61-adae-bd6e9503c014/%E1%84%89%E1%85%A5%E1%86%A8%E1%84%8B%E1%85%B2%E1%84%89%E1%85%B5%E1%84%8E%E1%85%AE-1.drawio.png" title="" alt="석유시추-1.drawio.png"></p>
28+
29+
<p>예를 들어 가로가 8, 세로가 5인 격자 모양의 땅 속에 위 그림처럼 석유가 발견되었다고 가정하겠습니다. 상, 하, 좌, 우로 연결된 석유는 하나의 덩어리이며, 석유 덩어리의 크기는 덩어리에 포함된 칸의 수입니다. 그림에서 석유 덩어리의 크기는 왼쪽부터 8, 7, 2입니다. </p>
30+
31+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/0b10a9f6-6d98-44d6-a342-f984ea47315c/%E1%84%89%E1%85%A5%E1%86%A8%E1%84%8B%E1%85%B2%E1%84%89%E1%85%B5%E1%84%8E%E1%85%AE-2.drawio.png" title="" alt="석유시추-2.drawio.png"></p>
32+
33+
<p>시추관은 위 그림처럼 설치한 위치 아래로 끝까지 뻗어나갑니다. 만약 시추관이 석유 덩어리의 일부를 지나면 해당 덩어리에 속한 모든 석유를 뽑을 수 있습니다. 시추관이 뽑을 수 있는 석유량은 시추관이 지나는 석유 덩어리들의 크기를 모두 합한 값입니다. 시추관을 설치한 위치에 따라 뽑을 수 있는 석유량은 다음과 같습니다.</p>
34+
<table class="table">
35+
<thead><tr>
36+
<th>시추관의 위치</th>
37+
<th>획득한 덩어리</th>
38+
<th>총 석유량</th>
39+
</tr>
40+
</thead>
41+
<tbody><tr>
42+
<td>1</td>
43+
<td>[8]</td>
44+
<td>8</td>
45+
</tr>
46+
<tr>
47+
<td>2</td>
48+
<td>[8]</td>
49+
<td>8</td>
50+
</tr>
51+
<tr>
52+
<td>3</td>
53+
<td>[8]</td>
54+
<td>8</td>
55+
</tr>
56+
<tr>
57+
<td>4</td>
58+
<td>[7]</td>
59+
<td>7</td>
60+
</tr>
61+
<tr>
62+
<td>5</td>
63+
<td>[7]</td>
64+
<td>7</td>
65+
</tr>
66+
<tr>
67+
<td>6</td>
68+
<td>[7]</td>
69+
<td>7</td>
70+
</tr>
71+
<tr>
72+
<td>7</td>
73+
<td>[7, 2]</td>
74+
<td>9</td>
75+
</tr>
76+
<tr>
77+
<td>8</td>
78+
<td>[2]</td>
79+
<td>2</td>
80+
</tr>
81+
</tbody>
82+
</table>
83+
<p>오른쪽 그림처럼 7번 열에 시추관을 설치하면 크기가 7, 2인 덩어리의 석유를 얻어 뽑을 수 있는 석유량이 9로 가장 많습니다.</p>
84+
85+
<p>석유가 묻힌 땅과 석유 덩어리를 나타내는 2차원 정수 배열 <code>land</code>가 매개변수로 주어집니다. 이때 시추관 하나를 설치해 뽑을 수 있는 가장 많은 석유량을 return 하도록 solution 함수를 완성해 주세요.</p>
86+
87+
<hr>
88+
89+
<h5>제한사항</h5>
90+
91+
<ul>
92+
<li>1 ≤ <code>land</code>의 길이 = 땅의 세로길이 = <code>n</code> ≤ 500
93+
94+
<ul>
95+
<li>1 ≤ <code>land[i]</code>의 길이 = 땅의 가로길이 = <code>m</code> ≤ 500</li>
96+
<li><code>land[i][j]</code>는 <code>i+1</code>행 <code>j+1</code>열 땅의 정보를 나타냅니다.</li>
97+
<li><code>land[i][j]</code>는 0 또는 1입니다.</li>
98+
<li><code>land[i][j]</code>가 0이면 빈 땅을, 1이면 석유가 있는 땅을 의미합니다.</li>
99+
</ul></li>
100+
</ul>
101+
102+
<h6>정확성 테스트 케이스 제한사항</h6>
103+
104+
<ul>
105+
<li>1 ≤ <code>land</code>의 길이 = 땅의 세로길이 = <code>n</code> ≤ 100
106+
107+
<ul>
108+
<li>1 ≤ <code>land[i]</code>의 길이 = 땅의 가로길이 = <code>m</code> ≤ 100</li>
109+
</ul></li>
110+
</ul>
111+
112+
<h6>효율성 테스트 케이스 제한사항</h6>
113+
114+
<ul>
115+
<li>주어진 조건 외 추가 제한사항 없습니다.</li>
116+
</ul>
117+
118+
<hr>
119+
120+
<h5>입출력 예</h5>
121+
<table class="table">
122+
<thead><tr>
123+
<th>land</th>
124+
<th>result</th>
125+
</tr>
126+
</thead>
127+
<tbody><tr>
128+
<td>[[0, 0, 0, 1, 1, 1, 0, 0], [0, 0, 0, 0, 1, 1, 0, 0], [1, 1, 0, 0, 0, 1, 1, 0], [1, 1, 1, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0, 1, 1]]</td>
129+
<td>9</td>
130+
</tr>
131+
<tr>
132+
<td>[[1, 0, 1, 0, 1, 1], [1, 0, 1, 0, 0, 0], [1, 0, 1, 0, 0, 1], [1, 0, 0, 1, 0, 0], [1, 0, 0, 1, 0, 1], [1, 0, 0, 0, 0, 0], [1, 1, 1, 1, 1, 1]]</td>
133+
<td>16</td>
134+
</tr>
135+
</tbody>
136+
</table>
137+
<hr>
138+
139+
<h5>입출력 예 설명</h5>
140+
141+
<p><strong>입출력 예 #1</strong></p>
142+
143+
<p>문제의 예시와 같습니다.</p>
144+
145+
<p><strong>입출력 예 #2</strong></p>
146+
147+
<p><img src="https://grepp-programmers.s3.ap-northeast-2.amazonaws.com/files/production/5e619c77-c940-46e6-9520-e5769e49194c/%E1%84%89%E1%85%A5%E1%86%A8%E1%84%8B%E1%85%B2%E1%84%89%E1%85%B5%E1%84%8E%E1%85%AE-3.drawio.png" title="" alt="석유시추-3.drawio.png"></p>
148+
149+
<p>시추관을 설치한 위치에 따라 뽑을 수 있는 석유는 다음과 같습니다.</p>
150+
<table class="table">
151+
<thead><tr>
152+
<th>시추관의 위치</th>
153+
<th>획득한 덩어리</th>
154+
<th>총 석유량</th>
155+
</tr>
156+
</thead>
157+
<tbody><tr>
158+
<td>1</td>
159+
<td>[12]</td>
160+
<td>12</td>
161+
</tr>
162+
<tr>
163+
<td>2</td>
164+
<td>[12]</td>
165+
<td>12</td>
166+
</tr>
167+
<tr>
168+
<td>3</td>
169+
<td>[3, 12]</td>
170+
<td>15</td>
171+
</tr>
172+
<tr>
173+
<td>4</td>
174+
<td>[2, 12]</td>
175+
<td>14</td>
176+
</tr>
177+
<tr>
178+
<td>5</td>
179+
<td>[2, 12]</td>
180+
<td>14</td>
181+
</tr>
182+
<tr>
183+
<td>6</td>
184+
<td>[2, 1, 1, 12]</td>
185+
<td>16</td>
186+
</tr>
187+
</tbody>
188+
</table>
189+
<p>6번 열에 시추관을 설치하면 크기가 2, 1, 1, 12인 덩어리의 석유를 얻어 뽑을 수 있는 석유량이 16으로 가장 많습니다. 따라서 <code>16</code>을 return 해야 합니다.</p>
190+
191+
<hr>
192+
193+
<p><strong>제한시간 안내</strong></p>
194+
195+
<ul>
196+
<li>정확성 테스트 : 10초</li>
197+
<li>효율성 테스트 : 언어별로 작성된 정답 코드의 실행 시간의 적정 배수</li>
198+
</ul>
199+
200+
201+
> 출처: 프로그래머스 코딩 테스트 연습, https://school.programmers.co.kr/learn/challenges
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import java.util.*;
2+
3+
/*
4+
전략
5+
1. bfs로 맵의 석유를 체크
6+
-> 각 덩어리별 석유 크기 저장 (리스트)
7+
-> Land에 덩어리 번호로 체크
8+
2. 500^2으로 돌면서 열 마다 개수 세기(완탐)
9+
*/
10+
11+
class Solution {
12+
List<Integer> oil;
13+
int[][] land;
14+
boolean[][] visited;
15+
int n, m;
16+
17+
public int solution(int[][] land) {
18+
pre_setting(land);
19+
return search_oil();
20+
}
21+
22+
int search_oil(){
23+
boolean[] oil_check = new boolean[oil.size() + 1];
24+
int sum, cnt, answer;
25+
26+
answer = 0;
27+
for(int j = 0; j < m; j++){
28+
sum = 0;
29+
Arrays.fill(oil_check, false);
30+
31+
for(int i = 0; i < n; i++){
32+
cnt = land[i][j];
33+
if(cnt == 0 || oil_check[cnt]) continue;
34+
oil_check[cnt] = true;
35+
sum += oil.get(cnt - 1);
36+
}
37+
answer = Math.max(answer, sum);
38+
}
39+
return answer;
40+
}
41+
42+
43+
void pre_setting(int[][] land){
44+
n = land.length;
45+
m = land[0].length;
46+
oil = new ArrayList<>();
47+
this.land = land;
48+
49+
int oilCnt = 1;
50+
visited = new boolean[n][m];
51+
52+
for(int i = 0; i < n; i++){
53+
for(int j = 0; j < m; j++){
54+
if(visited[i][j] || this.land[i][j] == 0) continue;
55+
oil.add(bfs(i, j, oilCnt++));
56+
}
57+
}
58+
}
59+
60+
int bfs(int x, int y, int num){
61+
int[] dx = {-1, 0, 1, 0};
62+
int[] dy = {0, 1, 0, -1};
63+
int cnt = 1;
64+
Queue<node> q = new ArrayDeque<>();
65+
q.add(new node(x, y, num));
66+
visited[x][y] = true;
67+
land[x][y] = num;
68+
69+
node now;
70+
int nx, ny;
71+
while(!q.isEmpty()){
72+
now = q.poll();
73+
74+
for(int i = 0; i < 4; i++){
75+
nx = now.x + dx[i];
76+
ny = now.y + dy[i];
77+
78+
if(nx < 0 || n <= nx || ny < 0 || m <= ny || visited[nx][ny] || land[nx][ny] == 0) continue;
79+
visited[nx][ny] = true;
80+
land[nx][ny] = num;
81+
q.add(new node(nx, ny, num));
82+
cnt++;
83+
}
84+
}
85+
return cnt;
86+
}
87+
88+
}
89+
90+
class node{
91+
int x, y, oilCnt;
92+
node(int x, int y, int oilCnt){
93+
this.x = x;
94+
this.y = y;
95+
this.oilCnt = oilCnt;
96+
}
97+
}

0 commit comments

Comments
 (0)