본문 바로가기

PS/프로그래머스

[프로그래머스-탐욕법] 체육복_파이썬

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

 

코딩테스트 연습 - 체육복

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

programmers.co.kr


def solution(n, lost, reserve):
    students = [1] * n
    for r in reserve:
        students[r - 1] += 1
    for l in lost:
        students[l - 1] -= 1

    if students[0] == 0 and students[1] == 2:
        students[0] += 1
        students[1] -= 1

    for i in range(1, len(students) - 1):
        if students[i] == 0:
            if students[i - 1] == 2:
                students[i] += 1
                students[i - 1] -= 1
                continue
            if students[i + 1] == 2:
                students[i] += 1
                students[i + 1] -= 1
                continue

    if students[-1] == 0 and students[-2] == 2:
        students[-1] += 1
        students[-2] -= 1

    count = 0
    for i in range(len(students)):
        if students[i] >= 1:
            count += 1

    return count

내가 작성한 코드지만 참 무식하다ㅎㅎ

처음에 모든 학생들의 체육복 수는 1이지만, 도난을 당한다면 -1, 여분이 있다면 +1을 해야한다.

체육복 개수 세팅이 끝나면, 이제 체육복이 없는 학생에게 체육복을 빌려줄 차례다.

0번째 인덱스 학생과 -1번째 인덱스 학생은 한명한테만 체육복을 받을 수 있으므로 따로 처리하고

중간 학생들은 for문을 통해 한꺼번에 처리한다.

이제 체육복을 한 개 이상 가지고 있는 학생들의 수를 계산하면 답을 구할 수 있다. 


def solution(n, lost, reserve):
    _lost = [l for l in lost if l not in reserve]
    _reserve = [r for r in reserve if r not in lost]
    
    for r in _reserve:
        front = r - 1
        back = r + 1
        if front in _lost:
            _lost.remove(front)
        elif back in _lost:
            _lost.remove(back)
    
    return n - len(_lost)

먼저 _lost와 _reserve를 서로 중복되지 않게 만들어 준다.

그 다음, _reserve의 앞이나 뒤에게 체육복을 줄 수 있다면 _lost에서 해당 요소를 삭제한다.

마지막으로 모든 학생의 수에서 _lost의 개수를 빼면 정답이 나온다.