[BOJ] 20443. 배드민턴 대회
백준 20443번: 배드민턴 대회 풀이
[BOJ] 20443. 배드민턴 대회
Problem
$N$명의 참가자가 있다.
- 참가자 수를 4의 배수로 맞추기 위해, $0 \sim 3$명을 무작위로 추첨에서 제외한다.
- 남은 참가자들은 자신의 번호가 아닌 번호표를 뽑아야 한다. (자기 자신과 매칭되지 않음)
모든 경우의 수를 $1,000,000,007$로 나눈 나머지를 구하시오.
- $1 \le N \le 100$
1
2
3
4
5
Input:
4
Output:
9
(Explanation: 4 is divisible by 4. k=0. M=4. Derangement D4 = 9.)
Initial Thought (Failed)
단순히 순열(Permutation)을 생성해서 arr[i] != i 인지 확인하면 될까요?
- 순열의 개수: $N!$.
- $N=100$이면 $100!$은 계산 불가능한 큰 수입니다.
따라서 완전 순열 (Derangement) 공식을 사용해야 합니다.
Key Insight
이 문제는 두 단계로 나눌 수 있습니다.
- Selection: $N$명 중 조건을 만족하는 $M$명을 선택하는 방법의 수 $\binom{N}{M}$.
- $(N-k) \pmod 4 = 0$ 인 $k \in {0, 1, 2, 3}$를 찾습니다. $M = N-k$.
- Derangement: 선택된 $M$명이 모두 자기 자신이 아닌 번호를 뽑는 경우의 수 $D_M$.
완전 순열(교란 순열) 점화식: \(D_n = (n-1)(D_{n-1} + D_{n-2})\)
Step-by-Step Analysis
$N=5$일 때:
- Remainder check: $5 \pmod 4 = 1$. 따라서 $k=1$명을 제외해야 함. 남은 인원 $M=4$.
- Combination: 5명 중 4명 선택 $\binom{5}{4} = 5$.
- Derangement: $D_4 = 9$.
- $D_1 = 0$
- $D_2 = 1$ (21)
- $D_3 = 2$ (231, 312)
- $D_4 = 9$ (2143, 2341, 2413 …)
- Result: $5 \times 9 = 45$.
graph TD
A["Start: N"] --> B{"Calculate Remainder R = N % 4"}
B --> C["Exclude k = R people"]
C --> D["Target Size M = N - k"]
D --> E["Calculate Comb(N, M)"]
D --> F["Calculate Derangement D_M"]
E --> G["Multiply"]
F --> G
G --> H["Result % MOD"]
Solution
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import sys
# 입력 받기
input = sys.stdin.readline
N = int(input())
MOD = 1000000007
# 1. DP로 교란 순열(Derangement) 미리 계산
# D[n] = (n-1) * (D[n-1] + D[n-2])
D = [0] * (N + 1)
if N >= 2:
D[2] = 1
for i in range(3, N + 1):
D[i] = (i - 1) * (D[i - 1] + D[i - 2]) % MOD
# end for
# 2. 조합(Combination) 계산 함수
# N이 작으므로(100) 팩토리얼 없이 파스칼 삼각형이나 단순 반복문도 가능하지만,
# 여기서는 큰 수 계산을 고려하지 않아도 되므로 직접 계산 (모듈러 주의)
def combination(n, r):
if r < 0 or r > n:
return 0
num = 1
den = 1
for i in range(r):
num = num * (n - i)
den = den * (i + 1)
return (num // den) % MOD # 나눗셈이 딱 떨어지므로 정수 나눗셈 후 모듈러
# end def
# 3. 정답 계산
remainder = N % 4
M = N - remainder # 4의 배수가 되는 최대 인원
# 조합 * 교란순열
comb_val = combination(N, M)
derange_val = D[M]
print((comb_val * derange_val) % MOD)
Complexity
- Time Complexity: $O(N)$
- $D_N$ 테이블 채우기: $O(N)$.
- 조합 계산: $O(N)$ (혹은 $O(1)$ since $k \le 3$).
- Space Complexity: $O(N)$
- $D$ 배열.
Key Takeaways
| Point | Description |
|---|---|
| Derangement ($!n$) | 모든 원소가 자기 위치에 있지 않은 순열의 개수 |
| Recurrence | $D_n = (n-1)(D_{n-1} + D_{n-2})$ |
| Modular Arithmetic | 중간 계산 과정에서도 나머지 연산을 적용하여 오버플로우 방지 |
This post is licensed under CC BY 4.0 by the author.
![[BOJ] 20443. 배드민턴 대회](/scitechblog/assets/img/posts/algo/baekjoon_new.png)