题目连接:http://zuojie.3322.org:88/soj/problem.action?id=2666
Description
给你一个数 n (1 < n <= 1000000) ,求 n! (n的阶乘)的质因数分解形式,质因数分解形式为 n=p1^m1*p2^m2*p3^m3…… * 这里 p1 < p2 < p3 < …… 为质数 * 如果 mi = 1, 则 ^ mi 就不需要输出Input
输入是多case的,每行一个数n,1 < n <= 1000000,当n等于0时输入结束Output
每个n输出一行,为它的质因数分解形式Sample Input
6 7 0Sample Output
6=2^4*3^2*5 7=2^4*3^2*5*7Author
windy7926778
题目是windy教主出的,意在考察对质因数分解和阶乘的深入理解。
如果按照普通思维,分别从1分解到n的话,超时的可能性非常大,而且内存开销也极其庞大。
必须转换思维。直接从n下手。
举个例子
n!里面包含了多少个2,假设n=10
那么个数是:10/2+10/4+10/8=5+2+1
于是快速方法就得到了
我们这样就可以直接统计每一个素因子出现了多少次,而1000000以内的素因子个数总共只有7w多,也就是说O(n)的速度是可行的!
我的代码:
#include<stdio.h> #include<string.h> #define MAXN 1000000 typedef long long LL; bool flag[MAXN+1]; int prime[MAXN+1]; int ans[MAXN+1]; int MAX,num=0; void init() { LL i,j; for(i=2;i<=MAXN;i++) { if(!flag[i]) { prime[num++]=(int)i; for(j=i*i;j<=MAXN;j=j+i) flag[j]=true; } } } void solve(int n) { int i,N; for(i=0;prime[i]<=n&&i<num;i++) { N=n; while(N) { ans[i]=ans[i]+N/prime[i]; N=N/prime[i]; } } printf("%d=",n); if(ans[0]==1) printf("2"); else if(ans[0]>1) printf("2^%d",ans[0]); for(i=1;prime[i]<=n&&i<num;i++) { if(ans[i]==1) printf("*%d",prime[i]); else if(ans[i]>1) printf("*%d^%d",prime[i],ans[i]); } printf("\n"); } int main() { int n; init(); while(scanf("%d",&n)!=EOF) { if(n==0) break; memset(ans,0,sizeof(ans)); solve(n); } return 0; }