这题展示了将某个数字展示为素数的乘积的方式
本质上和分子和分母同时除以各自的最大公约数类似,但是速度比他们快多了
下面附上代码:
//汝佳大佬的暴力解法,将某个数字表示为素数的乘积,按照素数的系数来求解 //我一开始想的是使用在一开始看到的那样,分子分母约去最大公约数,但是这样是不行的,因为数字太多了 //不过反过来一想,之前的使用最大公约数的方式也可以使用这道题的素数法 //其实本质上都是一样的,只不过之前的那道题分母上只有一个数字,使用约去最大公约数的方式也不会有太多的时间复杂度 #include<cstdio> #include<cstring> #include<cmath> using namespace std; bool vis[10000 + 10]; void creat_primer_table(int m) { for(int i = 2;i * i <= m;i ++) { if(!vis[i]) { for(int j = i * i;j <= m;j = j + i) { vis[j] = 1; } } } } int e[10000 + 10]; void add_factorial(int n,int d) { for(int i = n;i >= 2;i--) { int k = i; for(int j = 2;;j++)//把一个数展开成各素数的方式 { if(!vis[j]) { while(k % j == 0) { e[j] = e[j] + d; k = k / j; } if(k == 1) break; } } } } int main() { int p,q,r,s; creat_primer_table(10000); while(scanf("%d%d%d%d",&p,&q,&r,&s) == 4) { memset(e,0,sizeof(e)); add_factorial(p,1); add_factorial(s,1); add_factorial(r - s,1); add_factorial(q,-1); add_factorial(p - q,-1); add_factorial(r,-1); double ans = 1; for(int i = 2; i < 10000; i++) { if(!vis[i] && e[i] != 0) ans = ans * pow((double)i,e[i]); } printf("%.5lf\n",ans); } return 0; }