UVA 10375
题意:P Q R S,求C(p,q)/C(r,s).
两种方法:
第一种,数据比较水,一乘一除,不会溢出。
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int main() { double p,q,r,s; while(cin>>p>>q>>r>>s) { double sum=1.0; if(p-q<q)q=p-q; if(r-s<s)s=r-s; for(int i=1;i<=q||i<=s;i++) { if(i<=q)sum=sum*(p-q+i)/i; if(i<=s)sum=sum*i/(r-s+i); } printf("%.5f ",sum); } }
第二种,唯一分解定理。
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<math.h> using namespace std; const int max_=10005; int tot; bool b[max_]; int e[max_]; int prime[max_]; void getprime()//素数表 { for(int i=2;i<max_;i++) { if(!b[i]){ prime[++tot]=i; for(int j=i+i;j<max_;j+=i) { b[j]=1; } } } } void add_integer(int n,int d)//d为1即乘,-1即除。 { for(int i=1;i<=tot;i++)//求出素数因子的指数 { while(n%prime[i]==0) { n/=prime[i]; e[i]+=d; } if(n==1) break; } } void add_factorial(int n,int d) { for(int i=1;i<=n;i++) { add_integer(i,d); } } /*int pow_q(int x,int n) { int res=1; while(n>0) { if(n&1) res*=x; x=x*x; n>>=1; } return res; }*/ int main() { int p,q,r,s; getprime(); while(cin>>p>>q>>r>>s) { memset(e,0,sizeof(e)); add_factorial(p,1); add_factorial(q,-1); add_factorial(p-q,-1); add_factorial(r,-1); add_factorial(s,1); add_factorial(r-s,1); double sum=1.0; for(int i=1;i<=tot;i++) { if(e[i]) { sum*=pow(prime[i],e[i]); } } printf("%.5f ",sum); } }