컴퓨터는 잘못이 없다..

[알고리즘]BOJ_1158_요세푸스 문제(파이썬 리스트가 empty될때까지 while문 돌리기, 데큐사용, join과 map사용으로 출력문 출력하기) 본문

공부/알고리즘(파이썬)

[알고리즘]BOJ_1158_요세푸스 문제(파이썬 리스트가 empty될때까지 while문 돌리기, 데큐사용, join과 map사용으로 출력문 출력하기)

도토리까꿍v 2021. 4. 13. 13:04
Contents 접기

#문제 링크

1158번: 요세푸스 문제 (acmicpc.net)

 

1158번: 요세푸스 문제

첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)

www.acmicpc.net

 

#문제

https://www.acmicpc.net/problem/1158
요세푸스 문제

시간 제한	메모리 제한	제출	정답	맞은 사람	정답 비율
2 초	256 MB	40449	19824	14361	49.176%

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

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 ≤ 5,000)

출력
예제와 같이 요세푸스 순열을 출력한다.

예제 입력 1
7 3
예제 출력 1
<3, 6, 2, 7, 5, 1, 4>

 

#답안

import sys
input=sys.stdin.readline

#큐 구현을 위해 deque라이브러리 사용
from collections import deque
queue=deque()

#숫자 2개를 입력받는다.
n, k = map(int, input().split()) #3 4 입력시 n=3, k=4로 들어감

#queue에 1부터 n까지 값 대입
for i in range(n) :
    queue.append(i+1)

#result용 빈 리스트 생성
result=[]

i=1
while queue : #not queue는 queue가 비어있음, queue는 큐가 차있음 큐가 차있다면 while문을 실행하라, 큐가 비면 while문을 빠져나가라
    if i%k == 0 :
        result.append(queue.popleft())
    else :
        queue.append(queue.popleft())
    #i를 증가시켜주기
    i=i+1

print('<'+', '.join(map(str,result))+'>')

▲답안 설명

 

 

#개선 답안

import sys
input=sys.stdin.readline

N, K = map(int, input().split())
stack = [i for i in range(1, N + 1)] #stack사용
result = []
temp = K - 1

for i in range(N):
    if len(stack) > temp:
        result.append(stack.pop(temp))
        temp += K - 1
    elif len(stack) <= temp:
        temp = temp % len(stack)
        result.append(stack.pop(temp))
        temp += K - 1

print('<'+', '.join(map(str,result))+'>')

▲개선 답안 설명

tmp의 변화를 살펴보고 stack에서 pop(특정인덱스) 하도록 구현하여 for문을 많이 돌지 않도록 구현하였다. 

Comments