문제 📄
내 풀이 💻
N, K = map(int, input().split())
arr = [i for i in range(1,N+1)]
result = []
index = 0
while len(arr)>0:
index += K-1
index %= len(arr)
result.append(arr[index])
del arr[index]
print("<",end='')
print(", ".join(map(str, result)), end='')
print(">")
문제에 주어진 것처럼 (N, K)가 (7, 3)일 때를 가정하고 문제를 풀어보자. 주어진 수의 배열이 1부터 7일 때 3번째 숫자를 제거하는 과정은 다음과 같다.
1 2 3 4 5 6 7 (3 제거할 차례, arr[2])
1 2 4 5 6 7 (6 제거할 차례, arr[4])
1 2 4 5 7 (2 제거할 차례, arr[1])
1 4 5 7 (7 제거할 차례, arr[3])
1 4 5 (5 제거할 차례, arr[2])
1 4 (1 제거할 차례, arr[0])
4 (4 제거할 차례, arr[0])
삭제할 index는 2씩 증가한다. 그리고 2번째에서 3번째 줄로 넘어갈 때 arr[4] 다음 arr[6]를 삭제할 차례가 되는데 그러면 배열의 크기를 넘으므로 (6 % 배열의 크기인 5)를 해서 arr[1]을 삭제할 차례가 오게 된다.
이를 일반화 하면
삭제할 index는 K-1 씩 증가하고, K-1씩 증가하는 index를 항상 배열의 크기보다 작게 유지하기 위해 배열의 크기로 나눈 나머지를 index로 한다고 할 수 있다.
Review 🙋♀️
- 처음 시도에서는 index += K-1이 아니라 index += 2로 써서 틀렸는데, 예제의 (7, 3)의 경우만 생각하고 만들어서 그렇다. 다음부터는 문제를 풀 때 예제의 특수한 상황의 도움을 받더라도 처음부터 일반화해서 코드를 짜는 연습이 필요할 것 같다.
- 이 문제는 주어지는 입력의 최대 크기가 그렇게 크지 않아서(1~5000) list 방식으로 풀었지만, deque로도 풀 수 있을 것 같다. 0부터 1씩 증가하면서 popleft() 하고 append()를 해서 왼쪽 것을 오른쪽에 더해주다가 K-1번째가 되면 popleft()한 뒤 오른쪽에 다시 추가하지 않고 결과 배열에 추가하는 식으로 하면 될 것 같다.
💡
print(", ".join(map(str, result)), end='')
정수값이 담긴 리스트의 내용물을 쉼표로 연결된 형태로 출력하기 위해
먼저 map으로 리스트의 내용물을 문자열 형태로 바꿔 준 다음, 리스트의 자료를 연결해서 출력해주는 함수인 join을 사용했다.
for문으로 리스트의 값과 ", "을 출력하고 마지막 값은 ", " 없이 따로 result[-1]로 출력해주는 것보다 한 줄로 간편하게 출력할 수 있다.
'알고리즘 이론 & 풀이 > 백준(BOJ)' 카테고리의 다른 글
[백준] 1026번 - 보물 (nodejs) (1) | 2023.10.28 |
---|---|
[백준] 2178번 - 미로 탐색 (0) | 2023.08.17 |
[백준] 1260번 - DFS와 BFS (js) (0) | 2023.08.17 |
[백준] 5598번: 카이사르 암호 (Python) (0) | 2021.10.25 |
[백준] 2444번: 별 찍기 - 7 (Python) (0) | 2021.10.25 |