이번 문제는 아래 링크에서 풀어볼 수 있습니다.
1158번: 요세푸스 문제
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000)
www.acmicpc.net
문제
요세푸스 문제는 다음과 같다.
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 n, k = map(int, sys.stdin.readline().rstrip().split()) def mySolution(n, k): nums = [] result = [] for num in range(1, n + 1): nums.append(num) idx = k - 1 while nums: left = [] right = [] if len(nums) >= k: popped = nums.pop(idx) result.append(str(popped)) for i in range(idx, len(nums)): left.append(nums[i]) for i in range(0, idx): right.append(nums[i]) nums = left + right else : popped = nums.pop(0) result.append(str(popped)) for num in nums: left.append(num) nums = left return f"<{', '.join(result)}>" print('mySolution', mySolution(n, k))
답안 1
파이썬 Ver.
from collections import deque import sys n, k = map(int, sys.stdin.readline().rstrip().split()) def answer1(n, k): people = deque() for i in range(1, n+ 1): people.append(i) result = [] while people: for _ in range(k - 1): people.append(people.popleft()) result.append(people.popleft()) return str(result).replace('[', '<').replace(']', '>') print('answer1', answer1(n, k))
자바스크립트/NodeJS Ver.const fs = require('fs'); const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt'; let input = fs .readFileSync(filePath) .toString() .trim() .split(' ') .map((val) => parseInt(val)); const [n, k] = input; const answer1 = (n, k) => { const people = []; for (let i = 1; i <= n; i++) people.push(i); const result = []; while (people.length) { for (let i = 0; i < k - 1; i++) { people.push(people.shift()); } result.push(people.shift()); } return `<${result.map((val) => String(val)).join(', ')}>`; }; console.log('answer1', answer1(n, k));
답안 2
파이썬 Ver.
import sys n, k = map(int, sys.stdin.readline().rstrip().split()) def answer2(n, k): people = [i for i in range(1, n + 1)] result = [] idx = 0 for _ in range(n): idx += k - 1 if idx >= len(people): idx %= len(people) result.append(str(people.pop(idx))) return f"<{', '.join(result)}>" print('answer2', answer2(n, k))
자바스크립트/NodeJS Ver.
const fs = require('fs'); const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt'; let input = fs .readFileSync(filePath) .toString() .trim() .split(' ') .map((val) => parseInt(val)); const [n, k] = input; const answer2 = (n, k) => { const people = []; for (let i = 1; i <= n; i++) people.push(i); const result = []; let idx = 0; for (let i = 0; i < n; i++) { idx += k - 1; if (idx >= people.length) { idx %= people.length; } result.push(people.splice(idx, 1)[0]); } return `<${result.map((val) => String(val)).join(', ')}>`; }; console.log('answer2', answer2(n, k));
답안 3
const fs = require('fs'); const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt'; let input = fs .readFileSync(filePath) .toString() .trim() .split(' ') .map((val) => parseInt(val)); const [n, k] = input; const answer3 = (n, k) => { const queue = [...new Array(n)].map((item, index) => (item = index + 1)); const result = []; let count = 1; while (queue.length) { const shifted = queue.shift(); if (count % k === 0) { result.push(shifted); } else { queue.push(shifted); } count++; } return `<${result.map((val) => String(val)).join(', ')}>`; }; console.log('answer3', answer3(n, k));
답안 4
const fs = require('fs'); const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt'; let input = fs .readFileSync(filePath) .toString() .trim() .split(' ') .map((val) => parseInt(val)); const [n, k] = input; const answer4 = (n, k) => { const arr = Array.from({ length: n }, (v, i) => i + 1); const result = []; for (let i = 0; i < n; i++) { for (let j = 1; j <= k; j++) { if (j === k) { result.push(arr.shift()); } else { arr.push(arr.shift()); } } } return `<${result.map((val) => String(val)).join(', ')}>`; }; console.log('answer4', answer4(n, k));
답안 5
const fs = require('fs'); const filePath = process.platform === 'linux' ? '/dev/stdin' : './input.txt'; let input = fs .readFileSync(filePath) .toString() .trim() .split(' ') .map((val) => parseInt(val)); const [n, k] = input; const answer5 = (n, k) => { const arr = Array.from({ length: n }, (v, i) => i + 1); const result = []; let cnt = 0; while (arr.length) { cnt = (cnt + k - 1) % arr.length; result.push(arr[cnt]); arr.splice(cnt, 1); } return '<' + result.join(', ') + '>'; }; console.log('answer5', answer5(n, k));
문제 풀이
나의 경우 인덱스를 기준으로 해당 값을 pop하여 정답 배열에 넣고 인덱스를 기준으로 리스트를 왼쪽, 오른쪽으로 나눈 다음 위치를 바꿔 합치는 식으로 접근했다. 이처럼 복잡하게 계산할 필요 없이 자료구조 중 큐를 활용한다면 쉽게 풀 수 있는 문제다.
답안 1을 예로 들자면 while 반복문을 돌면서 사람을 한 명씩 제거해나간다. 이때 k번째 바로 앞의 요소까지를 큐의 맨 뒤로 보내면 k번째 요소가 맨 앞으로 오게 되는데 이 k번째 요소를 정답 리스트에 쌓아나간다.
# k = 3을 예로 들자면
# for _ in range(k - 1)을 했을 경우 for 반복문은 2번 실행됨.
# [1, 2, 3, 4, 5, 6, 7] 1과 2가 리스트의 맨 끝에 차례로 삽입됨
# [3, 4, 5, 6, 7, 1, 2] for 반복문을 거친 뒤 큐는 다음과 같이 된다. 여기서 맨 앞의 요소, 즉 k번째 요소인 3을 결과 리스트에 쌓는다.
이렇게 큐 people의 k번째 요소가 result 리스트에 쌓이면 반복문을 빠져나와 결괏값을 출력한다.
함께 보기
https://infinitt.tistory.com/213
백준 (boj) 파이썬 - 1158 요세푸스 문제
문제 링크 : https://www.acmicpc.net/problem/1158 1158번: 요세푸스 문제 첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000) www.acmicpc.net N명의 사람들이 있고, K를 주기로 사람들
infinitt.tistory.com
백준 1158. 요세푸스 (with. Python) - 큐 문제에서 deque()는 필수 별꼬리 땅땅
1158\. 요세푸스정말 요로코롬 생각해보다가 번뜩 떠오른 큐!! k-1개 빼놓고 다시 뒤에 붙이고, k번째를 pop()해가면 되지 않을까\~~ 아이디어는 정답!! 하지만 내 코드.. 리스트로 구현하고 바로 오류
velog.io
https://velog.io/@rkio/%EB%B0%B1%EC%A4%80-Javascript-1158
https://rrecoder.tistory.com/197
'👩💻 Programming > Coding Test 문제 풀이' 카테고리의 다른 글
| [Baekjoon] 10799 쇠막대기(파이썬/자바스크립트/NodeJS) (0) | 2022.12.25 |
|---|---|
| [Baekjoon] 17413 단어 뒤집기 2(파이썬/자바스크립트/NodeJS) (1) | 2022.12.25 |
| [Baekjoon] 10845 큐(파이썬 python) (0) | 2022.12.23 |
| [Baekjoon] 1406 에디터(파이썬/자바스크립트/NodeJS) (0) | 2022.12.23 |
| [Baekjoon] 1874 스택 수열(파이썬 python) (0) | 2022.12.22 |
댓글