题目描述:
给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。
输入:
两个整数n(2<=n<=1000),a(2<=a<=1000)
输出:
一个整数.
样例输入:
6 10
样例输出:
1
思路:
求的是最大的k使得b可以被a^k整除,但是不可以被a^(k+1)整除。用的方法是求出所有b的素因子次方,看a中相应素因子次方,若没有,调过,若有,判断b的次方是a的次方的几倍,选择所有素因子中次方倍数最小的。这样才是可以满足b可以被a整除但再多一个次方就不可以了。
代码:
#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<math.h>
#define MAX 1002
using namespace std;
int a[1002];
int prime[1002];
int primeSize;
bool judge(int i) { //是素数?
if (i <= 1)
return false;
int bound = (int)sqrt((double)i)+1;
for (int j = 2; j <= bound; j++) {
if (i%j == 0)
return false;
}
return true;
}
void init() { //初始化,a[i]为1表示不是素数,a[i]为0是素数
primeSize=2;
for (int i = 0; i < MAX; i++) {
a[i] = 0 ;
}
a[0] = 1;
a[1] = 1;
a[2] = 0;
prime[1]=2;
for (int i = 3; i <= MAX; i++) {
if (a[i] == 1) //已经不是素数了
continue;
if (!judge(i)) { //不是素数
a[i] = 1;
if(i< (int)sqrt((double)MAX)){
for (int j = i*i; j <= (int)sqrt((double)MAX); j += i) {
a[j] = 1;
}
}
}
else
prime[primeSize++]=i;
}
}
int cnt[1002]; //n!中的a中所存因子数
int cnt2[1002]; //a中的中所存因子数
int main() {
int n,a;
init();
while(cin>>n>>a){
for(int i=1;i<primeSize;i++){
cnt[i]=cnt2[i]=0;//计数器清零
}
for(int i=1;i<primeSize;i++){ //将n!分解,遍历每一个0到1000的临时素数
int t=n; //临时保存n
while(t){
cnt[i]+=t/prime[i];
t/=prime[i];//依次计算t/prime[i]^k,累加其值,直到t/prime[i]^k变为0
}
}
int ans=123123123; //答案初始化为一个大整数,为取最小值做准备
for(int i=1;i<primeSize;i++){ //对a分解素因数
while(a%prime[i]==0){
cnt2[i]++;
a/=prime[i];
}
if(cnt2[i]==0) continue;//若素数不能从a中分解到,即其对应幂指数为0,则其不影响整体性,调过
if(cnt[i]/cnt2[i]<ans)
ans=cnt[i]/cnt2[i]; //统计这些商的最小值
}
cout<<ans<<endl;
}
return 0;
}
/**************************************************************
Problem: 1104
User: WZDCJ0206
Language: C++
Result: Accepted
Time:0 ms
Memory:1548 kb
****************************************************************/