Wannafly挑战赛25 A 因子
题目:
令 X = n!, 给定一大于1的正整数p 求一个k使得 p ^k | X 并且 p ^(k + 1) 不是X的因子。
(1e18>=n>=10000>=p>=2)
思路:
题意就是求n的阶乘中有多少个p,但是这里n很大,不能直接算,所以需要理解怎样简化这个问题
先将问题简化成p是一个质数,对于一个n的阶乘,我们可以将他化为n的阶乘中含有的p的倍数相乘,然后再乘以其他不能被p整除的数相乘
即n!=1*2*3*(...)*n,化简为n!=(p*2p*3p(...)*kp)*s(s为不能被p整除的数相乘后的数) 所以就可以得到最大值k=n/p。
每次求出n的个数的和就是m!中因子n的总个数。*/
#include <stdio.h>
int main(void)
{
int N,n,m,count;
scanf("%d",&N);
while(N--)
{ count=0;
scanf("%d%d",&n,&m);
while(n)
{
n=n/m;
count=count+n;
}
printf("%d\n",count);
}
return 0;
}
然后进行拓展,对于p是一个正整数,只需要将p进行质因数分解,对于p的每一个质因数都进行一次判断,就行了
#include <stdio.h> #include <iostream> #define INF 1e18+7 using namespace std; bool a[10005]; int b[10005]; int size; void Init() { size =0; for(int i=2; i<=10005; i++) { if(a[i]==true) continue; b[size++]=i; if(a[i]==false) { for(int j=i*i; j<=10005; j+=i) { a[j]=true; } } } } unsigned long long cnt1[10005],cnt2[10005]; int main() { unsigned long long n; int a; cin>>n>>a; Init(); for(int i=0; i<size; i++) { cnt1[i]=cnt2[i]=0; } for(int i=0; i<size; i++) { unsigned long long t=n; while(t) { cnt1[i]+=t/b[i]; t=t/b[i]; } } long long ans=INF; for(int i=0; i<size; i++) { while(a%b[i]==0) { cnt2[i]++; a/=b[i]; } if(cnt2[i]==0) continue; if(cnt1[i]/cnt2[i]<ans) ans=cnt1[i]/cnt2[i]; } cout<<ans<<endl; return 0; }