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<<" "; 70 printf("%.5lf ",ans); 71 } 72 return 0; 73 }