我觉得数学类的题目,每一道都有很好的解决方法,都很有保存的意义和价值。
这道题目里面,巧妙地运用了 唯一分解定理,辅以素数的eratosthenes筛法构造,很好地解决了题目。值得思考和深入的学习。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; vector<int> primes; const int maxn = 10005; int vis[maxn]; int e[maxn]; void pre_prime() { memset(vis,0,sizeof(vis)); for(int i=2;i<=(int)(sqrt(maxn)+0.5);i++) { if(!vis[i]) { for(int j=i*i;j<=maxn;j+=i) vis[j]=1; } } for(int i=2;i<=maxn;i++) if(!vis[i]) primes.push_back(i); // for(int i=0;i<primes.size();i++) // { // printf("%d ",primes[i]); // } // printf("\n%d\n",primes.size()); } void add_integer(int n,int d) { for(int i=0;i<primes.size();i++) { while(n%primes[i]==0) { n/=primes[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 main() { int p,q,r,s; pre_prime(); while(scanf("%d%d%d%d",&p,&q,&r,&s)!=EOF) { 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 ans=1; for(int i=0;i<primes.size();i++) { ans*=pow(primes[i],e[i]); } printf("%.5lf\n",ans); } return 0; }
用函数使代码更加条理清晰
用eratosthenes使构造素数表更快
如果忽略了素数是从2开始的话,此题会陷入死循环的境地。(出了错思维缜密仔细查找)
总之我觉得每道数学题的解决方法都很有意义,都很不平凡!
10375 - Choose and divide(唯一分解定理的运用 eratosthenes构造素数表)
时间: 2024-10-12 13:40:21