프로그래머스 체육복 코드 및 해설 (파이썬)

2021. 6. 1. 15:39algorithm

반응형

https://programmers.co.kr/learn/courses/30/lessons/42862

 

코딩테스트 연습 - 체육복

점심시간에 도둑이 들어, 일부 학생이 체육복을 도난당했습니다. 다행히 여벌 체육복이 있는 학생이 이들에게 체육복을 빌려주려 합니다. 학생들의 번호는 체격 순으로 매겨져 있어, 바로 앞번

programmers.co.kr

 

우선 answer에 체육 수업에 참여할 수 있는 최소 학생 수인 (전체 학생 수) - (체육복을 도난당한 학생 수)를 저장했습니다. 이후 lost와 reserve 모두 오름차순으로 정렬하고, 체육복을 도난당했지만 여벌의 체육복이 있는 학생 수 먼저 자신의 체육복을 입도록 했습니다. 이러한 학생들의 수를 구해 answer에 더해주고, 이들을 lost와 reserve에서 제거했습니다.
이후 체육복을 도난당한 학생을 하나씩 살펴보며 그 학생의 앞번호 학생이 여벌의 옷이 있는지 먼저 확인했습니다. 그렇다면 그 학생에게 빌리고, 아니라면 뒷번호 학생을 확인했습니다. 오름차순으로 정렬되어 있기 때문에 도난 당한 학생은 앞번호, 뒷번호 모두에게 빌릴 가능성이 있지만, 그 다음 도난 당한 학생은 현재 도난 당한 학생의 앞번호 학생에겐 절대 체육복을 빌릴 수 없기 때문입니다. 따라서 앞번호 학생이 빌려줄 수 있는지 먼저 확인해야 최대의 학생이 체육수업에 참여할 수 있습니다.
빌릴 수 있다면 answer를 1씩 증가하고, 빌려준 학생을 reserve에서 제거했습니다.

 

def solution(n, lost, reserve):
    # 빌려주기 전 체육 수업을 들을 수 있는 학생의 수 
    answer = n - len(lost)

    # 모두 오름차순으로 정렬
    lost.sort()
    reserve.sort()

    # 여벌의 체육복이 있고, 도난도 당한 학생 
    self_lend = set(lost) & set(reserve)
    # 자신의 여벌의 체육복을 입으면 되므로 이런 학생 수만큼 answer 증가 
    answer += len(self_lend)
    # 이미 계산했으므로 lost, reserve 리스트에 이런 학생 삭제 
    for sl in self_lend:
        lost.remove(sl)
        reserve.remove(sl)

    # 도난당한 학생들 중에서 
    for lo in lost:
        # 먼저 앞번호 학생한테 빌리기 시도 
        # 그래야 그 다음 도난당한 학생들이 뒷번호 학생한테 빌릴 수 있는 가능성 있어 최대한 많은 학생이 체육 수업을 들을 수 있음 
        if (lo-1) in reserve:
            reserve.remove(lo-1)
            answer += 1 
        # 앞번호 학생에게 빌릴 수 없으면 뒷번호 학생에게 빌릭 
        elif (lo+1) in reserve:
            reserve.remove(lo+1)
            answer += 1 

    return answer
반응형