【数论】计算组合数

问题 B(2713): [POJ2249]计算组合数

时间限制: 1 Sec   内存限制: 128 MB

题目描述

给定正整数n, k,计算C(n, k)。答案保证在2^31以内。

输入

多组数据,每组数据仅一行,即2个整数n和k (n>=1) and k (0<=k<=n). 

以2个0结束输入

输出

对每个数据,输出对应的答案 

样例输入

Copy (如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)

4 210 549 60 0

样例输出

625213983816

提示

#----------------------------------------------------------------------------------------------#
这种题还需要说吗,大大的水资源啊,怎么能浪费……
思路什么的不说什么了,先看 第一次 的代码:
#include<cstdio>
#define LL long long//虽然答案保证了在2^31内,但我还是用了longlong,以防万一
LL C(LL x,LL y)
{
    LL sum=1;
    for(int i=1;i<=y;i++)
        sum=sum*(x--)/i;//边乘边除不会有问题,因为我们计算的时候乘是从大到小,除是从小到大,始终都能整除
    return sum;
}
int main()
{
    LL a,b;
    while(1)
    {
        scanf("%lld%lld",&a,&b);
        if(!a&&!b) return 0;
        if(a==b||b==0) {printf("1\n"); continue;}//觉得有可能超时,便加上了这句
        printf("%lld\n",C(a,b));
    }
    return 0;
}
然后真的超时了………………【神尴尬】
所以。。算法肯定不能怎么改了,但我们知道组合数有个重要的性质(m>n):

于是,我们要加上这样一行:
if(b>a-b) b=a-b;
瞬间就1998ms变成了0ms……
正确代码:
#include<cstdio>
#define LL long long
LL C(LL x,LL y)
{
    LL sum=1;
    for(int i=1;i<=y;i++)
        sum=sum*(x--)/i;
    return sum;
}
int main()
{
    LL a,b;
    while(1)
    {
        scanf("%lld%lld",&a,&b);
        if(!a&&!b) return 0;
        if(a==b||b==0) {printf("1\n"); continue;}
        if(b>a-b) b=a-b;
        printf("%lld\n",C(a,b));
    }
    return 0;
}

                                                                                                                                 By WZY


转载于:https://www.cnblogs.com/LinqiongTaoist/p/7203740.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值