백준 11866 / 요세푸스

dogit·2021년 8월 3일
0

백준문제

목록 보기
41/67

문제

풀이

설명

'1부터 N까지 나열되어있는 수에서 매 회마다 K번째에 위치한 수를 뽑아내는 수열(요세푸스 수열)'을 구하는 문제이다.

1부터 7까지의 수에서 3번째 위치한 수 마다 제거한다고 하면

seq {1, 2, 3, 4, 5, 6, 7}, result {}

round 1 : seq {1, 2, 3, 4, 5, 6, 7}, result {3}

round 2 : seq {1, 2, 4, 5, 6, 7}, result {3, 6}

round 3 : seq {1, 2, 4, 5, 7}, result {3, 6, 2}

round 4 : seq {1, 4, 5, 7}, result {3, 6, 2, 7}

round 5 : seq {1, 4, 5}, result {3, 6, 2, 7, 5}

round 6 : seq {1, 4}, result {3, 6, 2, 7, 5, 1}

round 7 : seq {4}, result {3, 6, 2, 7, 5, 1, 4}

이 과정을 설명하자면
첫번째 회차에서 3번째 수를 찾아가서 제거하고
그 다음 회차부터는 제거된 수의 위치에서 3번째 수를 찾아가서 제거하는 패턴을 모든 데이터가 제거될 때 까지 반복하고 있다.

이 과정을 코딩으로 구현할때 보편적으로 큐를 사용한다.
여기서 큐를 사용할 때에는 K번째 수가 되기 직전까지 맨 앞의 원소를 K-1 번 꺼내오고(poll) 꺼내온 원소들을 맨 뒤로 넣는다.(offer)
그리고 K번째로 뽑힌(poll) 원소는 출력하면 되는 것이다.

round 1

loop 1 : {1, 2, 3, 4, 5, 6, 7} → {2, 3, 4, 5, 6, 7, 1}

loop 2 : {2, 3, 4, 5, 6, 7, 1} → {3, 4, 5, 6, 7, 1, 2}

loop 3 : {3, 4, 5, 6, 7, 1, 2} → 3 출력

round 2

loop 1 : {4, 5, 6, 7, 1, 2} → {5, 6, 7, 1, 2, 4}

loop 2 : {5, 6, 7, 1, 2, 4} → {6, 7, 1, 2, 4, 5}

loop 3 : {6, 7, 1, 2, 4, 5} → 6 출력

round 3

loop 1 : {7, 1, 2, 4, 5} → {1, 2, 4, 5, 7}

loop 2 : {1, 2, 4, 5, 7} → {2, 4, 5, 7, 1}

loop 3 : {2, 4, 5, 7, 1} → 2 출력

round 4

loop 1 : {4, 5, 7, 1} → {5, 7, 1, 4}

loop 2 : {5, 7, 1, 4} → {7, 1, 4, 5}

loop 3 : {7, 1, 4, 5} → 7 출력

round 5

loop 1 : {1, 4, 5} → {4, 5, 1}

loop 2 : {4, 5, 1} → {5, 1, 4}

loop 3 : {5, 1, 4} → 5 출력

round 6

loop 1 : {1, 4} → {4, 1}

loop 2 : {4, 1} → {1, 4}

loop 3 : {1, 4} → 1 출력

round 7

loop 1 : {4} → {4}

loop 2 : {4} → {4}

loop 3 : {4} → 4 출력

한마디로 K-1번만큼 poll과 offer을 한 뒤, K번 째 값을 poll만하고 해당 원소를 출력해주면 되는 것이다.

코드

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Num11866 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		Queue<Integer> q  = new LinkedList<>();
		
		int N = sc.nextInt();
		int K = sc.nextInt();
		
		for (int i = 1; i <= N; i++) {
			q.add(i);
		}
		
		StringBuilder sb = new StringBuilder();
		sb.append('<');
		
		while(q.size() > 1) {
			for(int i = 0; i<K-1; i++) {
				int val = q.poll();
				q.offer(val);
			}
			sb.append(q.poll()).append(", ");
		}
		
		sb.append(q.poll()).append('>');
		System.out.println(sb);
	}
}

코드설명

참고 :
출처 : https://www.acmicpc.net/problem/11866

profile
느리더라도 꾸준하게

0개의 댓글