-
给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。
-
两个整数n(2<=n<=1000),a(2<=a<=1000)
-
一个整数.
-
6 10
-
1
-
题目描述:
-
输入:
-
输出:
-
样例输入:
-
样例输出:
我看了很多博文,很多人写出来的代码其实是有bug的。此处首先先算出较小的数a的所有素因数,讲解可以看我的前一篇博文“
C语言求最大公约数、最小公倍数
”。再而就是用a的素因数去试探n!(这里其实是试探n,非n!)#include<stdio.h>
#include<math.h>
#define INF 32767
int prime[200];
int primesize;
bool mark[1000];
void init()
{//素数筛法:求出1~1000内的所有素数,并保存在prime素组中
primesize = 0;
for (int i = 0; i < 1000; i++) //初始化
mark[i] = false;
for (int i = 2; i < 1000; i++)
if(mark[i]==true) continue;
else
{
prime[primesize++]=i;
for (int j = i; j < 1000; j+=i)
mark[j]=true;
}
}
int main()
{
int n,a;
int sqrtnum;
int prime_num;
int primeofa[200][2]; //二维数组,第一维保存a的素因数值,二维保存其幂指数(次方)
init();
while (scanf("%d%d",&n,&a)!=EOF)
{
prime_num=0;
sqrtnum = (int)sqrt(double(a))+1;
for (int i = 0; i < 200; i++) primeofa[i][1]=0;
for (int i = 0; i < primesize && prime[i]<sqrtnum;i++)//分解出a的所有素因数
{
if(a%prime[i]==0) //prime[i]是n的素因数
{
primeofa[prime_num][0]=prime[i];
while (a%prime[i]==0)
{
primeofa[prime_num][1]++;
a/=prime[i];
}
prime_num++;
}
if(a==1) break;
}
if (a!=1)
{
primeofa[prime_num][0]=a;
primeofa[prime_num][1]++;
prime_num++;
}
int j;
bool CanDivde = true; //n!能否整除a标志
int count_min=INF;
int c=0;
for (int i = 0; i < prime_num&&CanDivde; i++) //本循环求出n!是a的k倍
{
j=1;
if(n/primeofa[i][0]==0) CanDivde = false; //a的某个素因数不是n!的因数,n!不能被a整除
else
{
c= 0;
while(n/primeofa[i][0]>0) //若该a的素因数也是n!的素因数
{
int pownum =(int)pow(double(primeofa[i][0]),double(j));//取素因数的j次方
c+=n/pownum; //累加该素因数的幂指数
j++;
if(n/pownum==0) break; //该素因数的幂指数个数统计完毕,退出
}
if(c < primeofa[i][1]) CanDivde = false; //a与n!存在相同的素因数,但该素因数在a中的次数高于n!中的,n!也不能被a整除
else c /= primeofa[i][1]; //求n!中该素因数幂指数是a中该幂指数的倍数
if(count_min>c) count_min = c; //找出最小倍数,即为所求
}
}
if(CanDivde) printf("%d\n",count_min); //该值即为所求
else printf("-1\n"); //n!不能整除a在输出-1
}
return 0;
}
黑框运行结果: