题目:
给定n,a(2<=n,a<=1000),求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。
思路:
过程:
一开始,用直白解法(求n!,再循环除以a),问题出在n!可能会大到溢出。
所以,转成用求质因数的方式来求k。
代码:
1 #include <iostream> 2 #include <stdio.h> 3 #include <cstring> 4 using namespace std; 5 6 //相关变量 7 int prime[10]; //存放质因数(一个不超过1000的数,其质因数最多为4种) 8 int aExp[10]; //a的质因数的指数 9 int nExp[10]; //n对应于a质因数的指数 10 11 //求一个数的分解质因数,返回除1外质因数种类数 12 int questPrime(int a); 13 14 //主函数 15 int main(){ 16 int n,a,k,n2; 17 int typeNum,i,j; //typeNum:a的质因数种类数 18 while(scanf("%d %d",&n,&a)!=EOF){ //输入n,a 19 //初始化变量 20 memset(prime,0,10*sizeof(int)); 21 memset(aExp,0,10*sizeof(int)); 22 memset(nExp,0,10*sizeof(int)); 23 24 typeNum=questPrime(a); //a的分解质因数 25 while(n!=1){ //从n到2分解 26 n2=n; 27 for(i=0;i<typeNum;i++){ //遍历a的所有质因数 28 if(n2<prime[i]) //已小于该质因数,则肯定不含后续的更大的质因数,跳出for循环 29 break; 30 while(n2%prime[i]==0){ //因数中包含prime[i]质数,求该质因数的指数,放nExp[]中 31 nExp[i]++; 32 n2=n2/prime[i]; 33 } 34 } 35 n--; //分解下一个数 36 } 37 //求k 38 k=10000; //k初始化 39 for(i=0;i<typeNum;i++){ //n!和a的对应质因数的指数相除,k一定是最小的那个商 40 j=nExp[i]/aExp[i]; 41 if(j<k) 42 k=j; 43 } 44 printf("%d\n",k); //输出结果:k 45 } 46 return 0; 47 } 48 49 //求一个数的分解质因数,返回除1外质因数种类数 50 int questPrime(int a){ 51 int i=2,n=0; 52 bool boo=false; 53 if(a==1) //a=1 54 return 0; 55 else{ //a!=1 56 while(a!=1){ //a变成1时表示分解完 57 while(a%i==0){ //找到质因数 58 aExp[n]++; //该质因数的指数加1 59 a=a/i; 60 boo=true; 61 } 62 if(boo){ //boo保证该if语句块只在内层循环退出时执行一次 63 prime[n]=i; //记录该质因数 64 n++; //质因数种类数加1 65 boo=false; 66 } 67 i++; //找下一个因数 68 } 69 } 70 return n; //返回除1外质因数种类数 71 }