1010 다리놓기(C++)
구현 문제인척 하는 큰 수 처리 문제
1. 문제
간단 설명
N개의 사이트에서 M개의 사이트로 겹치지 않는 다리를 놓는 문제
M개 중 N개를 선택하는 전형적인 조합 문제
2. 문제 분석
주의점
- N, M의 최대값은 30이다
조합 공식
nCr = n! / ((n-r)! * r! )
을 이용해서 풀 경우, int형으로30!
는 처리가 불가능함30!
은2.6525286e+32
로 정수형 최대 큰 자료형인 unsigned long long int 형으로도 처리가 불가능하다 (약1.8e+19 까지 처리 가능)
- 조합 공식을 조금 수정해서
nCr = (n * n-1 * ... * n-r+1) / (r * r-1 * ... * 2 * 1)
로 풀이
30C15
인 경우,30 * 29 * ... * 15
또한 오버플로우가 남
- float, double 형 사용
- 부동 소수점은 정수를 다루는 용도로 사용하면 오차가 발생할 수 있으므로 사용하면 안됨!
알고리즘
계산하면서 오버플로우가 발생하지 않도록 처리해줘야한다
1
2
3
4
5
1. 테스트케이스 개수 T입력받기
2. N과 M입력 받기
3. N또는 M이 0이라면 불가능하므로 0 출력 후 다음 케이스로 넘어감
4. result 변수에 M부터 M-N+1 까지 차례로 곱해주면서, 1부터 N까지 나눠주는것을 동시에 진행한다
5. 출력 후 2로 돌아간다
필요변수
테스트 케이스 개수
int T
N, M
최대 30결과값
result
는 최대한 큰 수를 다룰 수 있도록 unsigned long long int 사용nCr
에서 r을 담당할int r
3. 소스코드
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
#include <iostream>
using namespace std;
int main() {
// freopen_s(new FILE*, "input.txt", "r", stdin);
int T, N, M;
cin >> T;
while (T--) {
cin >> N >> M;
if (N == 0 || M == 0) {
cout << 0 << endl;
continue;
}
unsigned long long int result = 1;
int r = 1;
for (int i = M; i >= M - N + 1; i--) {
result *= i;
result /= r;
r++;
}
cout << result << endl;
}
return 0;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.