study gomi

[백준/baekjoon] 12789번 도키도키 간식드리미 (파이썬) 본문

Practice/Baekjoon

[백준/baekjoon] 12789번 도키도키 간식드리미 (파이썬)

공부하곰 2024. 1. 14. 12:43
728x90
반응형

내 제출

- 나는 다다다다 코드를 작성하는 능력은 없음.

- 뭐가 필요한 지 주석 달고 코드를 작성하면서 문제 이해하고 푸는 편인데

- 이번에는 주석으로 굳이 추가 설명 없이도 코드 설명이 다 된 것 같다.

- 아무튼 이런 이유로 코드에 대한 추가 설명은 없음.

# 현재 대기열에서 맨 앞의 학생을 확인
# 이 학생의 번호가 현재 간식을 받을 수 있는 순서라면 받게 내보냄.
# 받을 수 없는 순서라면 임시 줄 서는 곳으로 보냄.
# 대기열의 학생 전부 처리 후 임시 줄서는 곳 학생들 다시 확인
def can_receive_snacks(waiting_student, waiting_n):
    # 현재 대기열
    cur_line = waiting_n

    # 임시 공간
    # [5,4,3,...] 이런 식으로 내림차순으로 들어가야 한다.
    # [5,4]인 상태에서 3은 들어갈 수 있지만 6은 못 들어간다.
    tmp_line = []

    # 간식 받으러 나가야 하는 번호의 학생
    # 초기 : 한 명도 안 나간 상태이고 학생들의 번호는 1,2,..,N
    # 즉 가장 먼저 1번이 받게 하기 위해 처음엔 1로 초기화.
    expected_num = 1

    # 줄 서있는 학생들을 검사해서
    while cur_line:
        # 지금 간식 받을 순서가 된 학생이라면
        if cur_line[0] == expected_num:
            # 그대로 내보내고
            cur_line.pop(0)
            # 그 다음 간식 받을 학생 번호 저장
            expected_num += 1
        # 받을 순서가 안 된 학생이라면 임시 공간으로 보냄.
        else:
            # 임시 공간에 줄 못 서는 경우
            if tmp_line and tmp_line[-1] < cur_line[0]:
                # 제대로 정렬할 수 없어서 break
                return "Sad"
            # 임시 공간에 줄 설 수 있는 상태면 집어 넣음.
            tmp_line.append(cur_line.pop(0))

        # 일단 현재 학생 처리 후 대기열 검사했는데
        # 현재 학생이 (예_3번) 간식 받으러 나갔고
        # 마침 대기열 학생들이 [7,5,4]로 3 다음으로 나가야 하는 상태면 내보냄.
        while tmp_line and tmp_line[-1] == expected_num:
            tmp_line.pop()
            expected_num += 1

    return "Nice" if expected_num - 1 == waiting_student else "Sad"


# 사용자 입력 받기
n = int(input())
line = list(map(int, input().split()))

# 결과 출력
print(can_receive_snacks(n, line))  # "Nice" or "Sad"

 

문제 접근

- 현재 줄(cur_line이라고 함.)에서 맨 앞 사람을 확인

- 이 사람이 받아야 할 순서의 번호와 일치하면 간식 받는 줄(get_line)로 보냄.

- 일치하지 않는다면 임시 대기 공간(tmp_line, stack으로 사용)으로 이동시킨다.

- tmp_line(스택)의 맨 위의 사람이 받아야 할 순서의 번호와 일치한다면, 그 사람을 간식 ㅂ다는 줄로 보냄.

- 이 과정을 더 이상 일치하는 사람이 없을 때까지 반복.

- 모든 사람을 처리한 뒤, 모든 학생들이 간식을 받았다면 'Nice', 그렇지 않다면 'Sad'를 출력

 

결과

- 두 번 틀린 뒤에 맞았다.

- 첫 번째 틀린 이유는 '기대 번호'라는 것을 굳이 사용 안 하고 조건문 분기로만 다 처리했는데 반복문 조건 실수.

- 경우의 수가 너~무 많아서 분기도 그만큼 많아서 힘들었다. 그래서 그냥 코드 아예 다시 짰다.

- 두 번째 틀린 이유는 대기열에서 학생 내보낼 때 한 명씩만 내보냈음.

- 한 명 내보냈는데 그 다음 대기열 학생이 바로 그 다음 간식 받을 순서인 경우를 생각 못 했다.

- 여튼 이거는 while문 넣어서 대기열 학생 뺄 수 있을 만큼 다 빼는 거 추가했더니 정답이었다.

 

더보기

- omg 이것도 silver3이라니.?ㅅ?

- 근데 딱히 자료구조를 어려운 걸 쓴다든가... 구현이 너무 어렵다든가... 하는 건 아직 없는 것 같다.

- 그래도 맨날 틀린다.

- 문제 이해하고 예외 상황 없게 구성하는 게 어려운 것 같다.

- 그것만 되면 코드는 그래도 금방 작성하는 듯..?

 

728x90
반응형