[백준] 11025. 요세푸스 문제 3

gong_ryong·2023년 8월 21일
0
post-custom-banner

문제 링크

1. 문제 설명

요세푸스 문제는 다음과 같다.

1번부터 N번까지 N명의 사람이 원을 이루면서 앉아있고, 양의 정수 K(≤ N)가 주어진다. 이제 순서대로 K번째 사람을 제거한다. 한 사람이 제거되면 남은 사람들로 이루어진 원을 따라 이 과정을 계속해 나간다. 이 과정은 N명의 사람이 모두 제거될 때까지 계속된다. 원에서 사람들이 제거되는 순서를 (N, K)-요세푸스 순열이라고 한다. 예를 들어 (7, 3)-요세푸스 순열은 <3, 6, 2, 7, 5, 1, 4>이다.

N과 K가 주어지면, 마지막으로 남는 사람의 번호를 구하는 프로그램을 작성하시오.

입력
첫째 줄에 N과 K가 빈 칸을 사이에 두고 순서대로 주어진다. (1 ≤ K ≤ N ≤ 5,000,000)

출력
첫째 줄에 마지막으로 남는 사람의 번호를 출력한다.

2. 문제 접근

요세푸스 문제의 일반해를 구하는 문제입니다.

전에 올렸던 카드2 문제처럼 K=2일 경우에는 비교적 쉽게 마지막에 남는 카드를 빠르게 구할 수 있습니다. 전체 카드의 수가 NN일 때 한 사이클이 끝난 후 남은 카드의 수는 N(K1)KN * \frac{(K-1)}{K}이므로 N=2iN = 2^i(i = 자연수)일 때 첫 번째 카드가 남는다는 것을 찾을 수 있습니다.

하지만 K > 3일 경우 (K+1K)i(\frac{K+1}{K}) ^ i가 정수일 수 없습니다. 따라서 K가 주어졌을 때 전체 사이클에 몇 장이 남았을 때 마지막 카드가 1일 것이다! 라는 그리디한 해를 구할 수 없습니다.

문제의 알고리즘 분류가 DP이므로 점화식을 구해 아래서부터 올라가야 합니다. N = 1이면 당연히 1이고 N = 2이면 (1 + K) % 2 (값이 0이면 2) 식으로 구할 수 있습니다. 이를 점화식으로 표현하면 다음과 같습니다.

J(n,k)=(J(n1,k)+m1)(mod n)+1J_{(n,k)} = (J_{(n-1,k)} + m - 1)(mod \ n) + 1

J(n1,k)+m=nJ_{(n-1,k)} + m = n일때 0이 나오므로 빼기에 약간 주의해야 합니다.

N, K 범위가 크지 않으므로 일반적인 DP처럼 풀어도 시간 초과가 나지 않습니다.

3. 문제 풀이

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringTokenizer st = new StringTokenizer(br.readLine());
		int n = Integer.parseInt(st.nextToken());
		int m = Integer.parseInt(st.nextToken());
		int ans = 1;
		for (int i =1; i <= n; i++) ans = (ans + (m-1)) % i + 1;
		System.out.println(ans);
	}
}
profile
비전공자의 비전공자를 위한 velog
post-custom-banner

0개의 댓글