- 오블완
- Baekjoon
- Unix_System
- Artificial_Intelligence
- programmers
- kubeflow
- datastructure
- codingTest
- Image_classification
- Python
- app
- Univ._Study
- Algorithm
- c++
- 자격증
- study
- C
- Database_Design
- 티스토리챌린지
- Personal_Study
- Kubernetes
- SingleProject
- tensorflow
- Operating_System
- 리눅스마스터2급
- Android
- 2023_1st_Semester
- Java
- cloud_computing
- Linux
코딩 기록 저장소
[프로그래머스/Python] [PCCP 기출문제] 2번 / 석유 시추 본문
문제 정보
제목 : [PCCP 기출문제] 2번 / 석유 시추
난이도 : Lv.2
사용 언어 : Python
문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/250136
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
문제 설명
[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]
세로길이가 n 가로길이가 m인 격자 모양의 땅 속에서 석유가 발견되었습니다. 석유는 여러 덩어리로 나누어 묻혀있습니다. 당신이 시추관을 수직으로 단 하나만 뚫을 수 있을 때, 가장 많은 석유를 뽑을 수 있는 시추관의 위치를 찾으려고 합니다. 시추관은 열 하나를 관통하는 형태여야 하며, 열과 열 사이에 시추관을 뚫을 수 없습니다.
예를 들어 가로가 8, 세로가 5인 격자 모양의 땅 속에 위 그림처럼 석유가 발견되었다고 가정하겠습니다. 상, 하, 좌, 우로 연결된 석유는 하나의 덩어리이며, 석유 덩어리의 크기는 덩어리에 포함된 칸의 수입니다. 그림에서 석유 덩어리의 크기는 왼쪽부터 8, 7, 2입니다.
시추관은 위 그림처럼 설치한 위치 아래로 끝까지 뻗어나갑니다. 만약 시추관이 석유 덩어리의 일부를 지나면 해당 덩어리에 속한 모든 석유를 뽑을 수 있습니다. 시추관이 뽑을 수 있는 석유량은 시추관이 지나는 석유 덩어리들의 크기를 모두 합한 값입니다. 시추관을 설치한 위치에 따라 뽑을 수 있는 석유량은 다음과 같습니다.
시추관의 위치 | 획득한 덩어리 | 총 석유량 |
1 | [8] | 8 |
2 | [8] | 8 |
3 | [8] | 8 |
4 | [7] | 7 |
5 | [7] | 7 |
6 | [7] | 7 |
7 | [7, 2] | 9 |
8 | [2] | 2 |
오른쪽 그림처럼 7번 열에 시추관을 설치하면 크기가 7, 2인 덩어리의 석유를 얻어 뽑을 수 있는 석유량이 9로 가장 많습니다.
석유가 묻힌 땅과 석유 덩어리를 나타내는 2차원 정수 배열 land가 매개변수로 주어집니다. 이때 시추관 하나를 설치해 뽑을 수 있는 가장 많은 석유량을 return 하도록 solution 함수를 완성해 주세요.
제한 사항
- 1 ≤ land의 길이 = 땅의 세로길이 = n ≤ 500
- 1 ≤ land[i]의 길이 = 땅의 가로길이 = m ≤ 500
- land[i][j]는 i+1행 j+1열 땅의 정보를 나타냅니다.
- land[i][j]는 0 또는 1입니다.
- land[i][j]가 0이면 빈 땅을, 1이면 석유가 있는 땅을 의미합니다.
정확성 테스트 케이스 제한사항
- 1 ≤ land의 길이 = 땅의 세로길이 = n ≤ 100
- 1 ≤ land[i]의 길이 = 땅의 가로길이 = m ≤ 100
효율성 테스트 케이스 제한사항
- 주어진 조건 외 추가 제한사항 없습니다.
입출력 예
land | result |
[[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]] | 9 |
[[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]] | 16 |
입출력 예 설명
입출력 예 #1
문제의 예시와 같습니다.
입출력 예 #2
시추관을 설치한 위치에 따라 뽑을 수 있는 석유는 다음과 같습니다.
시추관의 위치 | 획득한 덩어리 | 총 석유량 |
1 | [12] | 12 |
2 | [12] | 12 |
3 | [3, 12] | 15 |
4 | [2, 12] | 14 |
5 | [2, 12] | 14 |
6 | [2, 1, 1, 12] | 16 |
6번 열에 시추관을 설치하면 크기가 2, 1, 1, 12인 덩어리의 석유를 얻어 뽑을 수 있는 석유량이 16으로 가장 많습니다. 따라서 16을 return 해야 합니다.
나의 풀이
BFS를 정의합니다. row와 col의 값을 받아와서 큐에 추가하고 queue에 요소가 있는 동안 반복하는 while루프를 이용해 다음 갈 y, x를 구해 석유가 있는데 방문 안한 곳이라면 방문했다고 표시하고, 큐에 좌표를 추가 후 oil의 값을 1 추가합니다. 석유가 분포하는 열을 알아내기위해 set에도 저장후 while루프가 종료되면 answer의 석유가 분포하는 부분에 oil 값을 더합니다.
땅의 가로길이만큼 반복하는 for루프를 이용해 땅의 세로 길이로 파고 들어가면서 석유가 있는데 방문 안했다면 BFS함수를 수행합니다. 모든 반복이 끝나면 answer 리스트의 최댓값을 return합니다.
코드
from collections import deque
def solution(land):
answer = [0 for _ in range(len(land[0]))]
visitedLand = [[0 for _ in range(len(land[0])) ] for _ in range(len(land))]
def BFS(row,col):
dy = [1,0,-1,0]
dx = [0,1,0,-1]
queue = deque()
queue.append([row,col])
oil = 1
visitedLand[row][col] = 1
visitedX = {col} # 석유가 분포하는 열 추가함
while queue :
curY,curX = queue.popleft()
for i in range(4) :
nextY = curY+dy[i]
nextX = curX+dx[i]
if(0<=nextY<len(land) and 0 <= nextX < len(land[0])):
if (visitedLand[nextY][nextX] == 0 and land[nextY][nextX] == 1 ):
visitedLand[nextY][nextX] = 1
queue.append([nextY,nextX])
oil += 1
visitedX.add(nextX)
for v in visitedX : # 석유 분포하는 부분 answer에 추가함
answer[v] += oil
for i in range(len(land[0])): # 시추관의 위치 (땅의 가로길이)
for j in range(len(land)): # 땅 파고 들어감 (땅의 세로 길이)
if( land[j][i] == 1 and visitedLand[j][i] == 0) :
BFS(j,i)
return max(answer)
'프로그래머스 > Lv.2' 카테고리의 다른 글
[프로그래머스/Python] 유사 칸토어 비트열 (0) | 2024.03.20 |
---|---|
[프로그래머스/Python] 3 x n 타일링 (0) | 2024.03.20 |
[프로그래머스/Python] 교점에 별 만들기 (0) | 2024.03.19 |
[프로그래머스/Python] 택배 배달과 수거하기 (0) | 2024.03.18 |
[프로그래머스/Python] 순위 검색 (0) | 2024.03.18 |