Baekjoon Online Judge
문제
요세푸스 문제는 다음과 같다.
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)
출력
예제와 같이 요세푸스 순열을 출력한다.
예제 입력 | 예제 출력 |
7 3 | <3, 6, 2, 7, 5, 1, 4> |
풀이
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Queue queue = new Queue();
queue.max = in.nextInt(); // 사람의 수
int K = in.nextInt(); // 양의 정수 K
queue.init(); // 큐 초기화
queue.print(K); // 형식에 맞게 출력
}
}
class Queue {
int max;
int front;
int rear;
int[] data;
// 큐 초기화
void init() {
front = 0;
rear = 0;
data = new int[max + 1];
for (int i = 1; i <= max; i++)
enqueue(i);
}
// 큐에 데이터 입력
void enqueue(int n) {
data[++rear % (max + 1)] = n;
}
// 큐에서 데이터 삭제
int dequeue() {
return data[++front % (max + 1)];
}
// 공백 여부 확인
Boolean isEmpty() {
return (front == rear);
}
// 형식에 맞게 출력
void print(int k) {
System.out.print("<");
while(true) {
for (int i = 1; i < k; i++)
enqueue(dequeue());
System.out.printf("%d", dequeue());
if (!isEmpty())
System.out.print(", ");
else
break;
}
System.out.println(">");
}
}
원형큐를 이용해서 문제를 풀었다.
// 큐 초기화
void init() {
front = 0;
rear = 0;
data = new int[max + 1];
for (int i = 1; i <= max; i++)
enqueue(i);
}
큐를 초기화하는 코드이다. 1부터 입력한 숫자까의 숫자를 배열로 구현한 큐에 순서대로 입력한다.
// 형식에 맞게 출력
void print(int k) {
System.out.print("<");
while(true) {
for (int i = 1; i < k; i++)
enqueue(dequeue());
System.out.printf("%d", dequeue());
if (!isEmpty())
System.out.print(", ");
else
break;
}
System.out.println(">");
}
문제를 풀기 위해서는 init으로 큐를 초기화한 뒤 이 함수를 호출해야 한다. 원을 이루며 앉아있는 사람 중 K번째 사람을 제거하기 위해서는 K번째보다 앞에 있는 사람이 사라져서 K가 가장 앞에 있어야 한다. 이를 위해 K번째가 맨 앞에 위치할 때까지 dequeue()를 호출해서 큐에서 데이터를 삭제했다. 삭제한 데이터가 영영 없어지면 안되므로 그 데이터를 enqueue()를 통해 큐에 다시 저장했다. 그리고 K번째 사람을 dequeue()로 삭제한 뒤 이를 출력했다.
그 뒤 큐가 비어있는지를 확인했는데, 만약 큐가 비어있지 않다면 뒤에 더 숫자를 출력해야 하므로 ", "를 출력하도록 했으며, 큐가 비어있다면 반복문을 종료하게끔 했다.
'백준 > JAVA' 카테고리의 다른 글
[Baekjoon/JAVA] 2083번 - 럭비 클럽 (0) | 2023.01.01 |
---|---|
[Baekjoon/JAVA] 1874번 - 스택 수열 (0) | 2022.10.12 |
[Baekjoon/JAVA] 10866번 - 덱 (0) | 2022.10.04 |
[Baekjoon/JAVA] 10845번 - 큐 (0) | 2022.10.03 |
[Baekjoon/JAVA] 2609번 - 최대공약수와 최소공배수 (0) | 2022.09.16 |