POJ2249 Binomial Showdown

本文介绍了一种高效计算组合数C(n,k)的方法,避免了直接使用公式带来的整数溢出问题。通过预先存储分子和分母,逐步消去最大公约数进行简化,最终利用long long类型变量计算出结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

In how many ways can you choose k elements out of n elements, not taking order into account? 
Write a program to compute this number.

Input

The input will contain one or more test cases. 
Each test case consists of one line containing two integers n (n>=1) and k (0<=k<=n). 
Input is terminated by two zeroes for n and k.

Output

For each test case, print one line containing the required number. This number will always fit into an integer, i.e. it will be less than 231
Warning: Don't underestimate the problem. The result will fit into an integer - but if all intermediate results arising during the computation will also fit into an integer depends on your algorithm. The test cases will go to the limit. 

Sample Input

4 2
10 5
49 6
0 0

Sample Output

6
252
13983816

题目大意:求 C ( n , k ) 

普通的公式肯定会 WA 。

可以将每个分子分母存起来,约去 gcd ,再用 long long 计算答案。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define MAXN 10010
using namespace std;
long long n,k,a[MAXN],b[MAXN];
inline int read(){
	int date=0,w=1;char c=0;
	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
	return date*w;
}
long long gcd(long long x,long long y){
	if(!y)return x;
	return gcd(y,x%y);
}
void work(){
	if(n-k<k)k=n-k;
	for(long long i=1;i<=k;i++){a[i]=i;b[i]=n-k+i;}
	for(int i=1;i<=k;i++)
	for(int j=2;j<=k;j++){
		if(a[j]==1)continue;
		long long g=gcd(b[i],a[j]);
		if(g!=1){b[i]/=g;a[j]/=g;}
		if(b[i]==1)break;
	}
	long long ans=1;
	for(int i=1;i<=k;i++)if(b[i]!=1)ans*=b[i];
	printf("%lld\n",ans);
}
int main(){
	while(1){
		n=read();k=read();
		if(n==0&&k==0)break;
		memset(a,0,sizeof(a));memset(b,0,sizeof(b));
		work();
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值