[백준] 20301번 반전 요세푸스

[백준] 20301번 반전 요세푸스

출처: [백준] 20301번 반전 요세푸스


시간 제한 메모리 제한 제출 정답 맞은 사람 정답 비율
1 초 (추가 시간 없음) 1024 MB 467 248 201 54.918%

문제

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

1번 사람 오른쪽에는 2번 사람이 앉아 있고, 2번 사람 오른쪽에는 3번 사람이 앉아 있고, 계속하여 같은 방식으로 N명의 사람들이 원을 이루며 앉아 있다. N번 사람 오른쪽에는 1번 사람이 앉아 있다. 이제 K(≤N)번 사람을 우선 제거하고, 이후 직전 제거된 사람의 오른쪽의 K번째 사람을 계속 제거해 나간다. 모든 사람이 제거되었을 때, 제거된 사람의 순서는 어떻게 될까?

이 문제의 답을 (N, K)–요세푸스 순열이라고 하며, (7, 3)–요세푸스 순열은 ⟨3,6,2,7,5,1,4⟩가 된다.

하지만 한 방향으로만 계속 돌아가는 건 너무 지루하다. 따라서 요세푸스 문제에 재미를 더하기 위해 M명의 사람이 제거될 때마다 원을 돌리는 방향을 계속해서 바꾸려고 한다. 이렇게 정의된 새로운 문제의 답을 (N, K, M)–반전 요세푸스 순열이라고 하며, (7, 3, 4)–반전 요세푸스 순열은 ⟨3,6,2,7,1,5,4⟩가 된다.

N, K, M이 주어질 때, (N, K, M)–반전 요세푸스 순열을 계산해 보자.


입력

첫째 줄에 정수 N, K, M이 주어진다. (1≤N≤5 000, 1≤K,M≤N)


출력

(N, K, M)–반전 요세푸스 순열을 이루는 수들을 한 줄에 하나씩 순서대로 출력한다.


예제 입력 1

1
7 3 4

예제 출력 1

1
2
3
4
5
6
7
3
6
2
7
1
5
4

출처


알고리즘 분류


소스코드 (최초)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import sys
from collections import deque

input = sys.stdin.readline

N, K, M = map(int, input().split())

people = deque(x for x in range(1, N + 1))

count = 0
direction = 1
while people:
if direction: # 오른쪽
for _ in range(K - 1):
people.append(people[0])
people.popleft()
elif not direction: # 왼쪽
for _ in range(K):
people.appendleft(people.pop())

print(people.popleft())
count += 1
if count == M:
count = 0
direction = not direction

소스코드 (수정)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import sys
from collections import deque

input = sys.stdin.readline

N, K, M = map(int, input().split())

people = deque(x for x in range(1, N + 1))

while people:
for _ in range(M):
people.rotate(-(K - 1)) # 오른쪽
if not people:
break
print(people.popleft())

for _ in range(M):
people.rotate(K) # 왼쪽
if not people:
break
print(people.popleft())

[백준] 20301번 반전 요세푸스

https://devch.co.kr/2021/07/23/BAEKJOON-20301-21-07-23/

Author

Chaehyeon Lee

Posted on

2021-07-23

Updated on

2021-07-30

Licensed under

댓글