质因数

九度1207:质因数的个数 题目地址:http://ac.jobdu.com/problem.php?pid=1207

题目描述:

求正整数N(N>1)的质因数的个数。
相同的质因数需要重复计算。如120=2*2*2*3*5,共有5个质因数。
输入:

可能有多组测试数据,每组测试数据的输入是一个正整数N,(1<N<10^9)。

输出:

对于每组数据,输出N的质因数的个数。

样例输入:
120
样例输出:
5
提示:

注意:1不是N的质因数;若N为质数,N是N的质因数。


解题思路:

利用素数筛选法的反向思维,当i = 2的这轮循环完成时,n的因数已经不再包含2以及2的倍数,同理当i=3时,n的因数不再包含3和3的倍数。所以当i=4时,n%4==0不成立,自动跳过合数因数...

#include<iostream>
#include<cmath>
using namespace std;
 
int main(){
    int n,res,i;
    while(cin >> n){
        res = 0;
        for(i = 2;i <= sqrt(n + 1);i++){
            if(n % i == 0){
                while(n % i == 0){
                    res++;
                    n = n / i;
                }
            }
        }
        if(n > 1) res++;
        cout << res << endl;
    }
     
    return 0;
}
 
/**************************************************************
    Problem: 1207
    User: cherish
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1532 kb
****************************************************************/


九度1104:整除问题 题目地址:http://ac.jobdu.com/problem.php?pid=1104 题目描述:

给定n,a求最大的k,使n!可以被a^k整除但不能被a^(k+1)整除。

输入:

两个整数n(2<=n<=1000),a(2<=a<=1000)

输出:

一个整数.

样例输入:
6 10
样例输出:
1

解题思路:
由于n最大时可以是1000,此时求n的阶乘再循环除以a,会超时。所以可以用分解质因数的方法来解该题。令n!=b,分别对a和b分解质因数。
所以,对于a中的每一个质因数p,如果b的质因数中p的指数小于a中p的指数,则b不可能被a整除。所以我们需要依次测试a的每一个质因数,确 定该质因数在b中的幂指数是在a中的多少倍,所有的倍数中最小(非负正整数)的即是我们要求的k;
#include<iostream>
using namespace std;
 
#define N 1001
int prime[N];
 
void initprime(){
    int i,j,cnt;
    for(i = 0;i < N;i++) prime[i] = 1;
    prime[0] = prime[1] = 0;
    for(i = 2;i < N;i++){
        for(j = 2;i * j < N;j++){
            if(prime[i] == 1)
                prime[i * j] = 0;
        }
    }
}
 
//分别用来存储n!和a的每个质因子的幂 
int prime1[N];
int prime2[N];
 
int main(){
    initprime();
    int n,a,i,ans;
    while(cin >> n >> a){
        for(i = 0;i < N;i++) prime1[i] = prime2[i] = 0;
        for(i = 2;i <= n;i++){//计算n!的质因数及该质因数的个数 
            if(prime[i] == 1){
                int t = n;
                while(t){
                    prime1[i] += t / i;
                    t = t / i;
                }
            }
        }
         
        ans = 100000;
        for(i = 2;i <= a;i++){
            if(prime[i] == 1){
                while(a % i == 0){
                    prime2[i]++;
                    a = a / i;
                }   
            }
            if(prime2[i] != 0){
                if(prime1[i] / prime2[i] < ans) ans = prime1[i] / prime2[i];
            }
        } 
        cout << ans << endl;
         
    }
     
}
 
/**************************************************************
    Problem: 1104
    User: cherish
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1532 kb
****************************************************************/
另外,这题有一个比较简单的解法。不用分解质因数的方法,也可以避免求阶乘使数据变大。把每一个当前数看做是(A*a+B)*a^k,前面的A 对于后面的计算没有意义,所以每次计算只需要保留比a小的B。
#include<iostream>
using namespace std;
 
int main(){
    int n,a,k,i,tmp;
    while(cin >> n >> a){
        k = 0;
        tmp = 1;
        for(i = 2;i <= n;i++){
            tmp *= i;
            while(tmp % a == 0){//在计算n!的过程中先把能整除a的数整除a,只保留不能整除的部分
                k++;
                tmp /= a;
            }
            tmp %= a;//保留不能整除a的余数
        }
        cout << k << endl;
    }
     
    return 0;
}
 
/**************************************************************
    Problem: 1104
    User: cherish
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1520 kb
****************************************************************/
九度1087:约数的个数 题目地址:http://ac.jobdu.com/problem.php?pid=1087 题目描述:

输入n个整数,依次输出每个数的约数的个数

输入:

输入的第一行为N,即数组的个数(N<=1000)
接下来的1行包括N个整数,其中每个数的范围为(1<=Num<=1000000000)
当N=0时输入结束。

输出:

可能有多组输入数据,对于每组输入数据,
输出N行,其中每一行对应上面的一个数的约数的个数。

样例输入:
5
1 3 4 6 12
样例输出:
1
2
3
4
6
解题思路: 用1 <= i <=num一个一个计算的方法在当num= 1000000000时超时。事实上只需要计算1<=i<=sqrt(num),因为当i>sqrt(num)时比较小的那个因数肯定已经计算过。
#include<iostream>
#include<cmath>
using namespace std;
 
int caldiv(int x){
    int i,res;
    res = 0;
    for(i = 1;i < sqrt(x);i++){
        if(x % i == 0) res += 2;
    }
    i = sqrt(x);
    if(i * i == x) res++; 
    return res;
}
 
int main(){
    int n,i,tmp;
    while(cin >> n){
        if(n == 0) break;
        for(i = 0;i < n;i++){
            cin >> tmp;
            cout << caldiv(tmp) << endl;
        }
    }
     
    return 0;
} 
/**************************************************************
    Problem: 1087
    User: cherish
    Language: C++
    Result: Accepted
    Time:150 ms
    Memory:1532 kb
****************************************************************/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值