【暑假】[数学]UVa 10375 Choose and divide

UVa 10375 Choose and divide

 

题目:

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19601

思路:

  maxn=10000 如果计算maxn!再保存的话显然装不下。

  但答案由阶乘的积或商组成,所以可以用唯一分解定理求解。大题思路就是把目前答案的质因子的指数用数组e保存,乘除都对e操作。

 

  需要注意的是筛法求素数优化后的写法。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<iomanip> 
 4 #include<vector>
 5 #include<cstring>
 6 #include<cmath>
 7 #include<algorithm>
 8 using namespace std;
 9 
10 const int maxn = 10000 + 10;
11 
12 vector<int> primes;
13 void make_primes() {
14     int vis[maxn];
15     memset(vis,0,sizeof(vis));
16     int m=sqrt(maxn+0.5);
17     for(int i=2;i<=m;i++) if(!vis[i])  {
18      primes.push_back(i);
19      for(int j=i*i;j<maxn;j+=i) vis[j]=1;
20     }
21     for(int i=m;i<maxn;i++)   //primes分两部分 m之后也有质数 不能忽略 
22      if(!vis[i]) primes.push_back(i);
23 }
24 /*
25 bool is_prime(int n) {
26   int m = floor(sqrt(n) + 0.5);
27   for(int a = 2; a <= m; a++)
28     if(n % a == 0) return false;
29   return true;
30 }
31 void make_primes(){
32     for(int i=2;i<=10000;i++)
33      if(is_prime(i)) primes.push_back(i);
34 }
35 */
36 
37 int e[maxn];    //第i个质数的指数 
38 
39 void add_integer(int x,int d){
40     for(int i=0;i<primes.size();i++) {
41         int m=primes[i];
42         while(x%m==0){
43             x/=m;  e[i]+= d;
44         } 
45         if(x==1) break;
46     }
47 }
48 void add_factorial(int x,int d){
49     for(int i=1;i<=x;i++) 
50       add_integer(i,d);
51 }
52 
53 int main() {
54     make_primes();  //return primes
55     int p,q,r,s;
56     while(cin>>p>>q>>r>>s) {
57         memset(e,0,sizeof(e));
58         //add_factorial(a,d); 向质子表中乘(a!)^d; 
59         add_factorial(p,1);
60         add_factorial(q,-1);
61         add_factorial(p-q,-1);
62         add_factorial(s,1);
63         add_factorial(r-s,1);
64         add_factorial(r,-1);
65         
66         double ans=1.0;
67         for(int i=0;i<primes.size();i++) 
68           ans *= pow(primes[i],e[i]);  
69         //cout<<setw(5)<<ans<<"\n";
70         printf("%.5lf\n",ans);
71     }
72     return 0;
73 }

 

你可能感兴趣的:(【暑假】[数学]UVa 10375 Choose and divide)