문제 정보
- 문제 링크: https://www.acmicpc.net/problem/6567
- 카테고리: 조합론, 수학, Polya 열거 정리
문제 요약
“Let it Bead” 회사는 c가지 색상의 비드로 길이 s인 팔찌를 만듭니다. 팔찌는 다음의 특징을 가집니다:
- 고리 형태로 시작과 끝이 없음
- 방향성이 없음 (회전 + 뒤집기 가능)
- 모든 색상의 비드를 무한정 사용 가능
각 테스트 케이스마다 만들 수 있는 서로 다른 팔찌의 개수를 구하는 문제입니다. 고유함을 판정할 때, 회전과 뒤집기로 같아지는 팔찌는 동일한 것으로 간주합니다.
제한 조건:
- c, s ≥ 1
- c·s ≤ 32 (c와 s의 곱이 32 이하)
입출력 형식
입력: 각 줄에 두 정수 c (색상 수), s (팔찌 길이)
- 입력은 c = s = 0일 때 종료
출력: 각 테스트 케이스마다 만들 수 있는 고유한 팔찌의 개수
예제
입력:
| |
출력:
| |
예제 설명:
- (1,1): 색 1개, 길이 1 → 1개 팔찌
- (2,1): 색 2개, 길이 1 → 색상 0 또는 1 → 2개 팔찌
- (2,2): 색 2개, 길이 2 → {0,0}, {1,1}, {0,1} (회전/뒤집기 동일) → 3개 팔찌
- (2,5): 색 2개, 길이 5 → 8개 팔찌
접근 개요
이 문제의 핵심은 대칭을 고려한 색칠 개수 세기입니다. 단순히 c^s를 하면 모든 경우를 세지만, 회전과 뒤집기로 동일한 것들이 여러 번 중복 계산됩니다.
Burnside의 보조정리를 사용하면:
- 대칭 그룹의 크기: 2s (회전 s개 + 뒤집기 s개)
- 각 대칭 변환에 대해 불변인 색칠 개수를 구함
- 평균 = (모든 변환에 대한 불변 색칠 수의 합) / (그룹 크기)
| |
회전 대칭 분석
길이 s인 팔찌를 k칸 회전시킬 때 불변이려면, 색 패턴이 gcd(k, s) 길이의 주기를 가져야 합니다.
d = gcd(k, s)라 하면, s/d개의 독립적인 주기 패턴이 있으므로:
- 불변인 색칠 수 = c^(s/d)
모든 회전에 대한 합:
| |
여기서 φ는 오일러 파이 함수입니다.
뒤집기 대칭 분석
팔찌를 뒤집을 때 불변이려면 좌우 대칭이어야 합니다.
s가 홀수인 경우:
- 각 뒤집기 축은 정확히 1개의 비드를 지남
- 축 위의 비드: 1개 (고정)
- 양쪽 대칭 위치의 비드: (s-1)/2쌍
- 불변 색칠: c^((s+1)/2)
- s개 축 모두에 대해: s × c^((s+1)/2)
s가 짝수인 경우:
- 비드를 지나는 축 (s/2개): 고정된 비드 2개 + (s-2)/2쌍 → c^(s/2+1)
- 비드 사이를 지나는 축 (s/2개): s/2쌍만 있음 → c^(s/2)
- 합계: (s/2) × c^(s/2+1) + (s/2) × c^(s/2)
알고리즘 설계
- 오일러 파이 함수 계산: φ(n)을 소인수분해로 구함
- 회전 대칭 처리: s의 모든 약수 d에 대해 φ(d) × c^(s/d) 계산
- 뒤집기 대칭 처리: s의 홀짝성에 따라 경우 분류
- Burnside 공식 적용: (회전 합 + 뒤집기 합) / (2s)
의사코드
| |
복잡도 분석
시간 복잡도: O(√s + d(s) × log s)
- φ(n) 계산: O(√s)
- s의 약수 개수: d(s) ≤ 32 (충분히 작음)
- 각 약수마다 거듭제곱: O(log s)
공간 복잡도: O(1)
구현
| |
Python 구현
| |
검증
예제 (2, 5) 검증:
회전:
- φ(1)=1, φ(5)=4
- rotation = 1×2^5 + 4×2^1 = 32 + 8 = 40
뒤집기 (5는 홀수):
- reflection = 5 × 2^3 = 40
결과: (40 + 40) / 10 = 8 ✓
코너 케이스 체크리스트
- ✓ s=1: φ(1)=1 → 계산 정상
- ✓ c=1: 모든 비드가 같은 색 → 결과는 항상 1
- ✓ 큰 s: c^(s/2)가 32 이하로 제한되므로 오버플로우 없음
- ✓ 소수 vs 합성수 s: 약수 계산이 일반적으로 처리됨
제출 전 점검
- ✓ 입력 0 0에서 종료
- ✓ 오일러 파이 함수 소인수분해 정확성
- ✓ 회전/뒤직기 경우 분류 정확성
- ✓ 정수 나눗셈 (2*s로 정확히 나누어떨어짐)
- ✓ 거듭제곱 계산 (오버플로우 검토)
참고자료
- Burnside의 보조정리: https://en.wikipedia.org/wiki/Burnside%27s_lemma
- Polya 열거 정리: https://en.wikipedia.org/wiki/P%C3%B3lya_enumeration_theorem
- 오일러 파이 함수: https://en.wikipedia.org/wiki/Euler%27s_totient_function
- 유사 문제: BOJ 1593 (육각형), BOJ 2110 (목걸이)
![Featured image of post [Algorithm] C++ 백준 6567번: 팔찌](/post/algorithm/2025-12-03-boj-6567-let-it-bead-polya-cpp-solution/wordcloud_hu_782282af5f4c18b2.png)
![[Algorithm] C++ 백준 16481번 원 전문가 진우 - 방접원과 내접원의 관계](/post/algorithm/2025-12-03-boj-16481-excircle-incircle-geometry-cpp-solution/wordcloud_hu_ee675f3393f22f00.png)
![[Algorithm] C++ 백준 27533번 따로 걸어가기](/post/algorithm/2025-12-03-boj-27533-walk-separately-lindstrom-cpp-solution/wordcloud_hu_bcc1a69354c31bd3.png)
![[Algorithm] C++ 백준 6567번: 팔찌](/post/algorithm/2025-12-03-boj-6567-let-it-bead-polya-cpp-solution/wordcloud_hu_9f7bf9b3b4a09b24.png)
![[Algorithm] C++ 백준 11869번: 님블](/post/algorithm/2025-12-02-boj-11869-nimble-game-theory-cpp-solution/wordcloud_hu_bf915b4163fb4e18.png)
![[Algorithm] C++ 백준 13310번: 먼 별](/post/algorithm/2025-12-02-boj-13310-distant-star-convex-hull-cpp-solution/wordcloud_hu_a2b702e9b0991507.png)
![[Algorithm] C++/Python 백준 10854번: Divisions - 약수 개수](/post/algorithm/2025-09-16-boj-10854-divisions-number-of-divisors-cpp-python-solution/wordcloud_hu_f2a53254f2f126b2.png)
![[Algorithm] C++/Python 백준 12735번: Boat](/post/algorithm/2025-08-14-boj-12735-boat-cpp-python-solution/wordcloud_hu_dfad17dd2b1a530d.png)
![[Algorithm] C++ 백준 5051번: 피타고라스의 정리 (mod n)](/post/algorithm/2025-10-14-boj-5051-pythagorean-mod-n-cpp-solution/wordcloud_hu_7e8a5079e9226a49.png)