코테 준비
[프로그래머스] 혼자 놀기의 달인
박수련
2024. 2. 29. 23:30
문제 요약
https://school.programmers.co.kr/learn/courses/30/lessons/131130
상자의 개수가 n일 때, 1부터 n까지의 숫자가 적혀있는 카드가 순서에 관계없이 n개의 상자에 하나씩 들어있다.
임의의 상자를 하나를 골랐을 때 나온 카드의 숫자가 8이면, 8번째 상자를 열어 카드를 확인한다.
이렇게 열어야 하는 상자가 이미 열려있을 때까지 이 과정을 반복한다.
이때 모든 상자가 열리면 0을 반환하고 그렇지 않다면 위 과정을 한번 더 실행한다.
과정이 끝나면 첫번째 과정에서 연 상자의 수와 두번째 과정에서 연 상자의 수를 곱한다.
이때 나올 수 있는 최대 점수를 구하는 문제이다.
접근
처음에는 문제가 너무 복잡하다고 생각했지만 예제를 직접 그려보면서 보니 사이클을 이루는 숫자 조합들을 찾고 크기가 가장 큰 두 그룹의 곱만 반환하면 된다는 게 보였다.
cards의 값을 check_box 함수를 통해 상자를 까보면서 visit에 v값으로 저장해주었다.
하나의 사이클이 끝나면 v+=1를 해주어 다른 그룹임을 표시했다.
v가 1이라면 check_box 함수가 한번만 실행된 것, 즉 한번에 모든 상자들이 열린 것이므로 0을 반환했고
그 외의 경우에 대해서는 각 사이클의 크기를 구해 가장 큰 값과 그 다음 큰 값을 곱해서 반환해주었다.
코드
def solution(cards):
def check_box(num):
nonlocal v
if visit[num] == v:
return
if visit[num] == -1:
visit[num] = v
check_box(cards[num] - 1)
visit = [-1] * len(cards)
v = 0
for card in cards:
if visit[card - 1] == -1:
check_box(card - 1)
v += 1
# 각 visit 그룹별로 가장 개수가 많은 2개 세기
if v==1:
return 0
cnt = [0] * v
for vi in visit:
cnt[vi] += 1
cnt.sort(reverse=True)
answer = cnt[0] * cnt[1]
return answer