[백준알고리즘-JAVA]11866번 풀이(요세푸스 문제) - 초보도 이해하는 풀이

[백준알고리즘-JAVA]11866번 풀이(요세푸스 문제) - 초보도 이해하는 풀이

안녕하세요

인포돈 입니다.

백준 알고리즘 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 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를 사용하였는데 그냥 큐를 사용해도 문제없습니다!

from http://infodon.tistory.com/87 by ccl(A) rewrite - 2021-09-12 10:01:08