안녕하세요
인포돈 입니다.
백준 알고리즘 11866번 풀이입니다.
* 참고사항
- 개발환경은 eclipse을 기준으로 작성되었습니다.
- java언어를 이용하여 문제를 풀이합니다.
- 알고리즘 문제는 풀이를 보고 해답을 찾는 것도 중요하지만 무엇보다 스스로 풀이를 시도해봐야 합니다!!
(해당 풀이를 보기 전 충분히 문제에 대해 고민해봐야 합니다!)
- 해당 풀이 말고도 수많은 풀이 방법이 존재합니다.
백준 11866 (요세푸스 문제)
문제
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.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Deque;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Main {
static int N;
static int K;
static Deque<Integer> q = new LinkedList<>();
static int count = 0;
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
K = Integer.parseInt(st.nextToken());
sb.append("<");
for(int i = 1 ; i <=N ;i++) {
q.add(i);
}
while(q.size()>1) {
if(count == K-1) {
sb.append(q.pop() + ", ");
count = 0;
} else {
q.add(q.pop());
count++;
}
}
sb.append(q.pop()+">");
System.out.println(sb);
}
}
무 이번 요세푸스 문제는 간단히 풀 수 있는 문제였습니다. 간단히 주어진 K에 따라 변하는 알고리즘만 구축한다면 되거든요. 크게 어려울 것 없으니 STEP을 쉬엄쉬엄 보셔도 됩니다!
알고리즘 흐름도
입력받기 -> 1 ~ N까지 큐에 넣어주기 -> K에 따라 값 출력하기 -> 출력하기
STEP1 1 ~ N까지 큐에 넣어주기
뭐 없습니다. 반복문을 활용해 주세요
for(int i = 1 ; i <=N ;i++) {
q.add(i);
}
STEP2 어떻게 구현할지 구상하고 구현하기
간단합니다. K일 때마다 큐에서 해당 값을 POP 해주면 됩니다. 이때 K라는 순서를 가졌다는 것을 알려주기 위해 COUNT라는 변수를 사용해 줍니다.
while(q.size()>1) {
if(count == K-1) {
sb.append(q.pop() + ", ");
count = 0;
} else {
q.add(q.pop());
count++;
}
}
저는 WHILE과 if문을 활용하여 구현하였고, k-1을 해준 이유는 count가 0부터 시작하기 때문이죠. 뭐 그렇게 안 하시려면 if문에 있는 count - 0;을 1로 바꿔주면 된답니다.
while q가 비어있을때까지 반복해라
if : 만약 k번쨰 순서의 숫자이면, 꺼내서 sb에 넣어줘라.
else : 만약 k 번쨰 순서의 숫자가 아니면 q의 첫 번째 값을 가지 마지막에 넣어주고 count를 1 증가해라
뭐 각자의 역할을 이정도로 생각하시면 되겠습니다~
*물론 LinkedList를 활용하는 게 좋고요 (큐를 구현할 때입니다.)
*저 같은 경우 deque를 사용하였는데 그냥 큐를 사용해도 문제없습니다!
'알고리즘 > 백준알고리즘' 카테고리의 다른 글
[백준알고리즘-JAVA]1021번 풀이(회전하는 큐) - 초보도 이해하는 풀이 (0) | 2021.09.14 |
---|---|
[백준알고리즘-JAVA]1966번 풀이(프린터 큐) - 초보도 이해하는 풀이 (0) | 2021.09.13 |
[백준알고리즘-JAVA]18258번 풀이(큐2) - 초보도 이해하는 풀이 (0) | 2021.09.10 |
[백준알고리즘-JAVA]1931번 풀이(회의실 배정) - 초보도 이해하는 풀이 (0) | 2021.09.09 |
[백준알고리즘-JAVA]1541번 풀이(잃어버린 괄호) - 초보도 이해하는 풀이 (0) | 2021.09.08 |