牛客竞赛 阶乘
https://ac.nowcoder.com/acm/contest/5505/C
暴力做法,从2开始循环质因数,对于每次一个质因数i,看p1当前能分解出多少个,然后再枚举n,看n最小为多少能做到质因数i的数量大于等于p1
代码中有句sum=max(sum,j);什么含义?你想如果我们之前求出n=9包含3的数量满足条件,那枚举5时得到n=10,10的阶乘是包含9的阶乘,也就是10!既满足质因数2也满足3,所以求最大max
代码内也有注释
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int t,p1,sum=0; 6 cin>>t; 7 while(t--){ 8 cin>>p1; 9 sum=0; 10 for(int i=2;i*i<=p1;++i) 11 if(p1%i==0) 12 { 13 int cnt=0; 14 while(p1%i==0) 15 { 16 p1/=i; 17 ++cnt; 18 }//当前质因子i在p1中的数量 19 int tmp=0; 20 int j; 21 for(j=i;;j+=i) 22 { 23 int n=j; 24 while(n%i==0) 25 { 26 n/=i; 27 ++tmp; 28 } //记录当前质因数在n中的数量 29 30 if(tmp>=cnt) break;//找到一个数,使得他的质因数i的数量多于等于p1 31 } 32 sum=max(sum,j); 33 // cout<<sum<<endl; 34 } 35 cout<<max(sum,p1)<<endl; 36 } 37 }
https://blog.nowcoder.net/n/aa5ff9efa80440c897a9aaae4401a467
还有一个二分解法的代码,二分解法的解析在下面的官方题解中
这里我们来说下,在judge代码中,为何是如此计算次数的;
举个例子: 假如mid=8,那么就有1 2 3 4 5 6 7 8这样几个数
假如现在我们有一个质数为2,让我们计算构成这些数的质数2的个数,计算如下:
8/2=4,有4个数是2的倍数,将不满足的数字(1,3,5,7)去掉
再将剩下的数除以2,为1 2 3 4
然后重复以上过程,就可以计算出在mid!中,质数2的个数为多少,然后跟满足条件进行比较即可
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5; 4 int p,num[maxn],primer[maxn],k; 5 bool judge(int x){ //判断函数 6 for(int i=1;i<=k;i++){ 7 int n=x,num_primer=0; 8 while(n){ 9 num_primer+=n/primer[i]; 10 n/=primer[i]; 11 } 12 if(num_primer<num[i]) return false; 13 } 14 return true; 15 } 16 void solve(){ 17 k=0; 18 for(int i=2;i*i<=p;i++){ //对质因数进行分解 19 if(p%i==0){ 20 primer[++k]=i; //注意这里是++k 21 while(p%i==0){ 22 num[k]++; 23 p/=i; 24 } 25 } 26 } 27 if(p>1) primer[++k]=p,num[k]++; 28 int l=1,r=1e9,ans; 29 while(l<=r){ 30 int mid=(l+r)/2; 31 if(judge(mid)){ //如果这时候的mid满足题意,但我们要求的是最小的,所以将区间移到左边,即将右限左移,mid-1 32 r=mid-1; 33 ans=mid; 34 } 35 else l=mid+1; 36 } 37 memset(num,0,sizeof(num)); //记住,因为这是多组测试,所以要将num数组置为0,以便不会影响下次 38 cout<<ans<<endl; 39 } 40 int main(){ 41 int t; 42 cin>>t; 43 while(t--){ 44 cin>>p; 45 solve(); 46 } 47 return 0; 48 }
这是官方题解()