본문 바로가기
Algorithm/백준

[Python] 백준 11866번 - 요세푸스 문제 0

by 애기 개발자 2022. 10. 18.
반응형

문제

요세푸스 문제는 다음과 같다.

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

 

요세푸스 문제 - 나무위키

마지막에 남는 수만 알아내면 되는 경우와, 제거된 수의 순서도 알아내야 하는 경우의 효율적인 풀이가 다르다. 본 항목에서 배열의 첫 번째 원소는 인덱스 1로 표시한다. 즉, 원소의 번호는 1부

namu.wiki

나무위키에 요세푸스 문제가 정렬된 것을 보았고

 

풀이방법을 보던 중 '큐'로 푸는 방법이 내가 찾던 방법과 유사해서 채택하게 되었다.

 

이제 코드로 보자

 

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(">")

큐를 이용하여

 

선형을 원형처럼 만들 수 있었다.

 

방법을 보자마자 딱 내가 찾던 방법이라 생각하였고 바로 이해하여 풀 수 있었다.

반응형

댓글