미소를뿌리는감자의 코딩

[백준 2024/02/14] 9863번 Calling All Programmers 본문

코딩 테스트/백준

[백준 2024/02/14] 9863번 Calling All Programmers

미뿌감 2024. 2. 14. 15:33
728x90

https://www.acmicpc.net/problem/9863

 

9863번: Calling All Programmers

A local radio station is holding a phone-in contest, and deejay J-Z Phus is in charge of administering the contest. He goes on the air at random times and announces things like “The fifth caller will get a chance for the grand prize.” At this point, th

www.acmicpc.net

 

1. 접근 방법

이번 문제는 문제를 푸는 것보다 문제를 해석 하는데 더 많은 시간을 쓴 것 같다.

 

간단히 문제 해석을 적어보자면 다음과 같다.

 

처음에는 해당 문제를 queue로 접근했다.

앞에서 하나씩 pop 하고 뒤에서 append를 하는 것을 반복하는 것을 생각하고 문제를 풀었다. 7 번째는 출력해주고 뒤에 append하지 않는 식으로 구성하였다.

예제 코드는 출력이 되었으나, 막상 백준에 넣어봤을 때 '런타임 에러' 가 발생하였다. 어떤 종류인 런타임 에러인지 알려주지 않아 이것저것 찾아보다가, index로 다시 접근하기로 마음 먹었다. 아직도 왜 런타임 에러가 발생한 지는 모르겠다.

 

아래는 런타임 에러가 발생한 코드이다. ** 수정 : PyPy3 가 아니라, python3로 제출하니 맞았다.

import queue


while True:
    n, m, k = map(int, input().split())
    if n==0 and m ==0 and k ==0:
        break
    q = queue.Queue()
    for i in range(1, n+1, 1):
        q.put(i)

    count = 0
    while not q.empty() and count < k:
        for _ in range(m-1):
            q.put(q.get())
        popped = q.get()
        count += 1

    print(popped)

 

이제 index로 접근하는 방법에 대해서 적어보도록 하겠다.

예제 입력 

10 7 5

 

예제 출력 

3

 

을 예시로 적어보겠다.

일단 list를 구성해주었다.

list[0] = 1

list[1] = 2

list[2] = 3

...

list[9] = 10

 

이렇게 구성해주었다.

idx        0 1 2 3 4 5 6 7 8 9
value     1 2 3 4 5 6 7 8 9 10

 

이후 없어지는 idx의 패턴은 다음과 같다.

현재 (idx + (m - 1)) % len(list)

현재 idx 에서 6을 이동하고, 만약 list 의 길이를 넘어서 이동했을 경우를 대비해서 list의 길이로 나머지를 구해준다.

여기서 len(list) 를 반복문 마다 다시해주는 이유는, 반복문 마다 list에서 하나씩 pop이 되기 때문이다. 

즉, list의 길이가 유동적으로 변하기 때문이다. 

 

7을 더하는 것이 아니라, 6을 더하는 것은, pop이 된 곳에서 부터 세기를 시작해야하기 때문이다. 

 

0 + 6 % 10 = 6

6 + 6 % 9 = 3

3 + 6 % 8 = 1

1 + 6 % 7 = 0

0 + 6 % 6 = 0

 

pop 이 되면서 idx 값이 유동적으로 바뀌게 됨을 이해해야 한다.

 

2. 코드

def find_kth_caller(n, m, k):
    callers = list(range(1, n + 1))
    index = 0

    for i in range(k-1):
        index = (index + m - 1) % len(callers)
        callers.pop(index)

    final_index = (index + m - 1) % len(callers)
    return callers[final_index]

while True:
    n, m, k = map(int, input().split())
    if n == 0 and m == 0 and k == 0:
        break
    print(find_kth_caller(n, m, k))
728x90