POJ Combinations

前言

好家伙题目差点看懵我,刚开始还以为要用高精度乘除,吓我一跳,幸好这道题以前做过还有点印象(哈哈)

一、分析

题目意思很明确是要你用这个公式了:C = N! / (N-M)!M!(虽然不知道那个100的阶乘给出来干嘛)
按照一般思路最开始肯定会想到高精度乘除去,但很明显太麻烦了。
仔细看这个公式就会发现虽然不能化简,但是如果我们真正代数运算时是可以划掉一些东西的,但是我们又没办法表示。
所以换一种思路,我们可以边乘边除,不难看出我们可以让N从(N-M+1)开始乘一个数就除一个数。这样的好处就是避免了要去使用高精度的问题。

二、代码

代码如下:

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
__int64 getCC(int n,int m)
{
    if(n==m||m==0) return 1;//这里要注意几个特判
    else if(n<m) return 0;
    else
    {
        n=n-m+1;
        __int64 sum=1;//范围得定义大一点,防止溢出
        for(int i=1;i<=m;i++)
        {
            sum=sum*(n++);//边乘边除
            sum/=i;
        }
        return sum;
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)==2)
    {
        if(n==0||m==0) break;
        printf("%d things taken %d at a time is %lld exactly.\n",n,m,getCC(n,m));

    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值