uva 10375 (重载运算符)

题意:已知C(m,n)=m! / (n!*(m-n!)),输入整数p,q,r,s(p>=q,r>=s,p,q,r,s<=10000),计算C(p,q)/C(r,s)。输出保证不超过10^8,保留5位小数

#include<iostream>
#include<cstring>
#include<cmath>
#include<iomanip>
#define f(i,l,r) for(i=(l);i<=(r);i++)
using namespace std;
const int MAXN=2000,MAXM=10000;
int p,q,r,s;
int Prime[MAXN],inp[MAXM+5];
struct bign{
    int w[MAXN],pos=0;
    bign(){
        memset(w,0,sizeof(w));
        pos=0;
    }
    bign(int x){
        int i;
        memset(w,0,sizeof(w));
        if(x==0) return;
        f(i,1,Prime[0]){
            while(x%Prime[i]==0){
                x/=Prime[i];
                w[i]++;
            }
            if(x==1){
                pos=i;
                break;
            }
        }
    }
    bign operator * (const bign &x){
        int i;
        bign ans;
        ans.pos=max(pos,x.pos);
        f(i,1,ans.pos){
            ans.w[i]=w[i]+x.w[i];
        }
        return ans;
    }
    bign operator / (const bign &x){
        int i;
        bign ans;
        ans.pos=max(pos,x.pos);
        f(i,1,ans.pos){
            ans.w[i]=w[i]-x.w[i];
        }
        return ans;
    }
};
bign Ans;
void Init()
{
    int i,j;
    f(i,2,MAXM){
        if(!inp[i]){
            Prime[++Prime[0]]=i;
        }
        f(j,1,Prime[0]){
            if(i*Prime[j]>MAXM) continue;
            inp[i*Prime[j]]=1;
            if(i%Prime[j]==0) break;
        }
    }
}
void Multi(int a,int flag)
{
    int i;
    f(i,2,a){
        bign tmp;
        tmp=bign(i);
        if(flag==1) Ans=Ans*tmp;
        else Ans=Ans/tmp;
    }
}
int main()
{
    int i;
    double ans;
    Init();
    while(cin>>p>>q>>r>>s){
        Ans=bign(0);
        ans=1;
        Multi(p,1);
        Multi(s,1);
        Multi(r-s,1);
        Multi(q,-1);
        Multi(p-q,-1);
        Multi(r,-1);
        f(i,1,Ans.pos){
            ans*=pow(Prime[i],Ans.w[i]);
        }
        cout<<fixed<<setprecision(5)<<ans<<endl;
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值