문제
요세푸스 문제는 다음과 같다.
1번부터 N번까지 N명의 사람이 원을 이루면서 앉아있고, 양의 정수 K(≤ N)가 주어진다. 이제 순서대로 K번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다. 원에서 사람들이 제거되는 순서를 (N, K)-요세푸스 순열이라고 한다. 예를 들어 (7, 3)-요세푸스 순열은 <3, 6, 2, 7, 5, 1, 4>이다.
N과 K가 주어지면 (N, K)-요세푸스 순열을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 1,000)
출력
예제와 같이 요세푸스 순열을 출력한다.
처음 난 이 문제를 보자마자
C언어 공부할때 배웠던 원형 연결리스트를 떠올렸다.
이를 파이썬의 배열로 충분히 구현이 가능하다 생각하여 먼저 배열로 구하고자 하였다.
n, k = map(int, input().split())
data = []
for i in range(n):
data.append(i+1)
idx = k
for i in range(n):
print(data[idx-1])
data.remove(data[idx-1])
idx += k
...
위와 같은 방식으로 구현하고자 하였으나 결국 배열은 배열이었고 원형 연결리스트가 아니었다.
idx의 값이 len(data)를 넘어서면서 계산이 어려워졌고 다른 방법을 찾아야만 했다.
이후 수학적으로 어떻게든 공식이 있지 않을까.. 해봤지만 실패했고
요세푸스 문제에 대한 방법을 얻기위해 인터넷에 검색을 해봤다.
https://namu.wiki/w/%EC%9A%94%EC%84%B8%ED%91%B8%EC%8A%A4%20%EB%AC%B8%EC%A0%9C#s-3.1.3
나무위키에 요세푸스 문제가 정렬된 것을 보았고
풀이방법을 보던 중 '큐'로 푸는 방법이 내가 찾던 방법과 유사해서 채택하게 되었다.
이제 코드로 보자
import sys
from collections import deque
queue = deque()
n, k = map(int, sys.stdin.readline().split())
data = []
for i in range(n):
queue.append(i+1)
print("<",end='')
while queue:
for _ in range(k-1):
tmp = queue[0]
queue.popleft()
queue.append(tmp)
if(len(queue) == 1):
print(queue[0], end='')
else:
print(queue[0], end=', ')
queue.popleft()
print(">")
큐를 이용하여
선형을 원형처럼 만들 수 있었다.
방법을 보자마자 딱 내가 찾던 방법이라 생각하였고 바로 이해하여 풀 수 있었다.
'Algorithm > 백준' 카테고리의 다른 글
[Python] 백준 1920번 - 수 찾기 (0) | 2022.10.20 |
---|---|
[Python] 백준 1018번 - 체스판 다시 칠하기 (1) | 2022.10.19 |
[Python] 백준 11650번 - 좌표 정렬하기 (0) | 2022.10.17 |
[Python]백준 10814번 - 나이순 정렬 (0) | 2022.10.15 |
[Python] 백준 2869번 - 달팽이는 올라가고 싶다 (0) | 2022.10.12 |
댓글