上交大 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 }

 

转载于:https://www.cnblogs.com/songshu-gancuimian/p/6651887.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值