jh05013   5년 전

단순히 조합을 구하는 문제이지만, 구하는 방법에 따라 자주 틀리는 요인이 있습니다.

  1. nCk를 n!/k!(n-k)!로 계산할 경우, 분자의 팩토리얼을 계산하면서 오버플로우가 날 수 있습니다. (파이썬은 정수 오버플로우가 없으므로 제외) 30팩토리얼은 무려 265252859812191058636308480000000, unsigned long long에도 담을 수 없을 정도로 큰 수입니다.

2. nCk를 n (n-1) ... (n-k+1) / k!로 계산할 경우 가능은 한데, 무턱대고 그냥 계산하면 마찬가지로 오버플로우가 납니다. nCk = nC(n-k)를 이용해 보세요.

3. 극도로 큰 수까지 나타낼 수 있는 double을 (파이썬은 float) 쓰면 되지 않느냐 하면 그것도 아닙니다. 부동소수점은 넓은 범위의 수를 나타내기 위해 어느 정도의 오차를 가지도록 설계되었기 때문에, 정수를 다루는 용도로는 절대 사용하면 안 됩니다. https://ko.wikipedia.org/wiki/...

계산 순서를 잘 바꿔서 큰 수가 나타나지 않도록 하면 int 오버플로우 없이도 정확한 값을 계산할 수 있습니다. 어떻게 하면 될까요?

jh05013   5년 전

30까지가 아니라 29까지군요. 낮에 수정하겠습니다.

infinitic   5년 전

자세한 설명 감사합니다

헷갈리는 게 있는데요,!

정수를 사용해서 팩토리얼을 계산했는데도 불구하고 오버플로우가 나는 건 숫자가 커서 오버플로우가 나는 것이고,

파이썬에서는 해당 사항이 없는데, 조합 계산 시 답이 틀렸다고 나오는 것은 정수형끼리 나눗셈을 하더라도 결과 값이 실수형이므로 결국 오차가 생기기 때문인 것이 맞지요?

그러면 정수만을 다루는, 정수로 나누어 떨어지는 나눗셈을 할 때에는 대부분의 경우에  / 대신 //을 사용하면 될까요? 

지금까지는 잘 모르고 그냥 나눗셈 후에 int를 씌웠는데, 앞으로는 꼼꼼히 살펴봐야 할 것 같습니다..

그리고 글 내용에서 계산 순서를 바꿔서 큰 수가 나타나지 않도록 하는 것은, 큰 수가 발생하는 연산 전에 약분을 하면 될 것 같은데

궁금하네요.. 초보라.. 팩토리얼을 포함한 조합 계산 함수가 인수를 두 개 받도록 정의하고, 곱하기 루프 돌 때 매번 최대공약수를 구해서 약분하면 될 것 같아요. 그런데 너무 느려지지 않을까 싶습니다

암튼 감사합니다

jh05013   5년 전

파이썬에서 int a와 b가 있을 때 a // b는 int 단위의 정확한 몫을 계산하여 int로 표시합니다. 따라서 //를 쓰면 오차가 없습니다.

올려주신 테스트케이스에서 제일 처음이 12가 되야 합니다.

테스트케이스의 개수가 12개 입니다.

jh05013   4년 전

감사합니다.

neku3219   4년 전

문제 풀이에 큰 도움이 되었습니다. 감사합니다.

댓글을 작성하려면 로그인해야 합니다.