본문 바로가기
👩‍💻 Programming/Coding Test 문제 풀이

[프로그래머스] level 1 체육복(파이썬 python)

by codingBear 2022. 12. 4.
728x90
반응형

문제

https://school.programmers.co.kr/learn/courses/30/lessons/42862?language=python3 

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr


정답 코드

나의 풀이(오답)
def mySolution(n, lost, reserve):
    uniformCnt = [1] * n

    for i in reserve:
        uniformCnt[i - 1] += 1

    for i in lost:
        uniformCnt[i - 1] -= 1

    answer = 0

    # 현재 탐색값이 맨 앞이거나 맨 뒤일 경우, 그리고 앞뒤 학생을 모두 확인해야 하는데 해당하는 조건문 처리가 빠짐.
    for i in range(n):
        if i - 1 > 0:
            if uniformCnt[i] > 1 and uniformCnt[i - 1] == 0:
                uniformCnt[i] -= 1
                uniformCnt[i - 1] += 1
            elif uniformCnt[i] > 1 and uniformCnt[i + 1] == 0:
                uniformCnt[i] -= 1
                uniformCnt[i + 1] += 1

    for cnt in uniformCnt:
        if cnt > 0:
            answer += 1

    return answer
Set을 활용한 풀이
def exampleAnswer1(n, lost, reserve):
    # 1. Set으로 중복 제거한다.
    reserveOnly = set(reserve) - set(lost)
    lostOnly = set(lost) - set(reserve)

    # 2. 여분을 기준으로 앞뒤를 확인하여 체육복을 빌려준다.
    for reserve in reserveOnly:
        front = reserve - 1
        back = reserve + 1

        # 앞 혹은 뒤에 있는 학생이 잃어버린 학생이라면 lostOnly에서 뺀다.
        if front in lostOnly:
            lostOnly.remove(front)
        elif back in lostOnly:
            lostOnly.remove(back)

    # 3. 전체 학생 수에 lostOnly에 남은 학생 수를 뺀다.
    return n - len(lostOnly)
배열을 활용한 풀이
def exampleAnswer2(n, lost, reserve):
    # 1. students 배열 생성
    students = [0] * (n + 2)

    # 2. students 배열에 reserve/lost 정보 반영
    for i in reserve:
        students[i] += 1
    for i in lost:
        students[i] -= 1

    # 3. 앞뒤 학생을 확인하며 빌려줄 수 있으면 체육복을 빌려준다.
    for i in range(1, n + 1):
        if students[i] > 0:
            front = i - 1
            back = i + 1
            if students[front] < 0:
                students[i] -= 1
                students[front] += 1
            elif students[back] < 0:
                students[i] -= 1
                students[back] += 1

    # 체육복을 갖고 있는 학생 수를 계산한다.
    answer = 0
    for i in range(1, n + 1):
        if students[i] >= 0:
            answer += 1

    return answer

문제 해설

 제한사항 마지막 부분에 '여별 체육복을 가져온 학생이 체육복을 도난당했을 수 있습니다.'라는 조건을 처리할 수 있는지가 이 문제를 푸는 데 핵심이다. 파이썬의 set을 활용해서 차집합을 만들면 쉽게 풀이할 수 있다.

 나의 경우 원래 내가 작성하고 싶었던 코드는 '배열을 활용한 풀이'의 코드이다. 체육복 개수를 담은 배열을 생성한 뒤 여벌이 있는 만큼 더하고, 체육복을 잃어버린 만큼 뺀다. 그 다음 앞뒤의 개수를 확인하며 체육복을 빌려줄 필요가 있다면 빌려주는 식으로 풀려고 했다. 허나 조건문 처리를 완벽하게 하지 못해 오답이 나오고 말았다.

 이와 같이 배열의 앞뒤를 탐색해야 할 필요가 있을 때 배열 앞뒤로 여분의 요소를 하나씩 덧붙여 놓으면 현재 확인하고 있는 요소가 맨 앞인지 맨 뒤인지 확인하는 조건문을 더 쓰지 않아도 된다.

728x90
반응형

댓글