ps:problems:boj:33911
특별상 눈치게임
ps | |
---|---|
링크 | acmicpc.net/… |
출처 | BOJ |
문제 번호 | 33911 |
문제명 | 특별상 눈치게임 |
레벨 | 실버 3 |
분류 |
수학 |
시간복잡도 | O(n+m) |
인풋사이즈 | n<=100, m<=100 |
사용한 언어 | Python 3.13 |
제출기록 | 34536KB / 36ms |
최고기록 | 36ms |
해결날짜 | 2025/05/23 |
풀이
- 팀의 수를 n, 정수의 범위를 m이라고 하자.
- n과 m이 작아서 에디토리얼의 풀이처럼 O(n + m^4)의 브루트포스로도 풀린다
- 좀더 효율적으로 풀려면, 특별상에 해당되는 점수를 X로 만드는 정수 조합의 개수를 각각 세어주는 방식으로 접근하자
- 내가 X점으로 특별상을 받기 위해서 반드시 선택해야 하는 수는
- X ⇒ 당연하다
- X보다 큰 수중에서 1명만 선택한 수 ⇒ 내가 그 수를 안고르면 그 수가 특별상이 되므로..
- 그리고 선택하면 안되는 수는
- X보다 큰 수중에서 아무도 선택하지 않은 수 ⇒ 그 수를 고르면 X가 아닌 그 수가 특별상이 된다.
- 그러면 X점으로 특별상을 받을수 있는 조합의 개수는 comb(100 - {선택하면 안되는 수의 개수} - {반드시 선택해야 하는 수의 개수}, 3 - {반드시 선택해야 하는 수의 개수}) 이다
- 따라서 먼저 각 수에 대해서 선택팀의 수를 구해놓은 다음에, X를 100부터 1까지 줄여가면서, 무조건 골라야 하는 수의 개수와 고르면 안되는 수의 개수를 관리하며 위의 식을 계산하면 된다. 각 X에 대한 값을 O(1)에 구할 수 있으므로 (comb(n,k)은 k가 2이하이므로 O(1)에 계산가능) 총 시간복잡도는 O(n+m)
코드
"""Solution code for "BOJ 33911. 특별상 눈치게임".
- Problem link: https://www.acmicpc.net/problem/33911
- Solution link: http://www.teferi.net/ps/problems/boj/33911
Tags: [ad hoc]
"""
import math
def main():
N = int(input())
counter = [0] * 101
for _ in range(N):
A, B, C = [int(x) for x in input().split()]
counter[A] += 1
counter[B] += 1
counter[C] += 1
answer = 0
cannot_select_count = must_select_count = 0
for i in range(100, 0, -1):
if counter[i] == 0:
answer += math.comb(
99 - cannot_select_count - must_select_count,
2 - must_select_count,
)
cannot_select_count += 1
elif counter[i] == 1:
must_select_count += 1
if must_select_count >= 3:
break
print(answer)
if __name__ == '__main__':
main()
ps/problems/boj/33911.txt · 마지막으로 수정됨: 2025/05/23 14:29 저자 teferi
토론