上交大 2011 整数问题

题目:
给定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 }

 

posted @ 2017-03-31 16:05  松鼠大战干脆面  阅读(126)  评论(0编辑  收藏  举报