조합의 수 (건국 기념일 파티 훈련 DAY1-B 오프 2019 소)

조합의 수 (국립 데이 파티 훈련 DAY1-B 오프 2019 소)

시간 제한 : C / C ++ 일초, 이초 언어, 다른
공간의 제한 : C / C ++ 32768K, 다른 언어는 65536k 나
특수 판사는 IO는 형식을 64 비트 : LLD의 %를

판단 : 조합의 수를

제목 설명

주어진 케이 케이 , 추구 나를 { ! 케이 ! ( - 케이 ) ! , 1 0 (18) } \ 최소 \ {\ FRAC {N} {K! (N - K)} 10 {18} ^ \} 값.
! = 1 × × × 엔! 1 = \ 시간 2 \ 시간 \ cdots \ N 배 나타냅니다 계승.

설명을 입력합니다 :

입력 파일은 파일의 단부에, 상기 처리를 복수의 데이터 세트를 포함한다.
각 데이터 세트는 두 정수 N과 K를 포함한다.

  • 0 k n 1 0 9 0 \ 당량 K \ 당량 n \ 당량 10 ^ 9

  • 올라 1 0 5 10 ^ 5 데이터 세트.

출력 설명 :

각 시험 출력 소망의 값을 나타내는 정수.

예 1

기입

1000000000 0
1000000000 2
1000000000 500000000

수출

1
499999999500000000
1000000000000000000

문제 해결

폭력,하지만 노트 데이터 오버 플로우

코드 (긴 이중 버전)

#include<bits/stdc++.h>
using namespace std;
long long INF = 1e18;
int n, m;
long double c;
int main() {
	while (cin >> n >> m) {
		m = min(n - m, m);
		c = 1;
		for (int i = 1; i <= m; i++) {
			c = c * (n - i + 1) / i;
			if (c > INF) break;
		}
		if (c > INF) cout << INF << endl;
		else cout << (long long)c << endl;
	}
}

코드 (__int128 버전)

#include<bits/stdc++.h>
using namespace std;
typedef __int128 ll;
const ll INF = 1e18;
const int N = 2e3 + 10;
int n, k;
ll ans;
int main() {
	while (~scanf("%d%d", &n, &k)) {
		if (k > n / 2)k = n - k;
		ans = 1;
		for (int i = 1; i <= k; ++i) {
			if (ans*(n - i + 1) / i <= INF)ans = ans * (n - i + 1) / i;
			else {
				ans = INF;
				break;
			}
		}
		printf("%lld\n", (ll)ans);
	}
	return 0;
}
게시 된 163 개 원래 기사 · 원의 찬양 (54) ·은 30000 +를 볼

추천

출처blog.csdn.net/weixin_42856843/article/details/101875642