牛客网计算机考研复试-KY3-约数的个数

题目链接:点这里


题目描述:
输入n个整数,依次输出每个数的约数的个数


思路1:
对每一个数计算其公约数,遍历1到sqrt(n)之间的数。


代码1:

#include <bits/stdc++.h>
using namespace std;
int main(){
    int n;
    while(cin>>n){
        for(int i=1;i<=n;i++){
            int m;
            cin >> m;
            int cnt = 0;
            for(int j=1;j*j<=m;j++){
                if(m%j==0)
                    cnt+=2;
                if(j*j==m)
                    cnt--;
            }
            cout << cnt << endl;
        }
    }
    return 0;
}

思路2:
当n非常大的时候,第一种方法显然会超时,这时我们可以使用素数筛来进行解题。

首先我们要是知道 约数个数定理(不明白可以点链接查看)

通过 埃氏筛法得到素数。
由于一个数x可以质因数分解为小于等于x的素数的n次方的乘积,我们通过计算素数的幂,然后将每个幂+1相乘,得到的就是所有的约数个数。
例如:

约数定理


代码2:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e4;
bool is_prime[maxn];
vector<int> prime;
void init(){
    for(int i=1;i<maxn;i++)
        is_prime[i] = true;
    is_prime[0] = false;
    is_prime[1] = false;
    for(int i=2;i<maxn;i++){
        if(is_prime[i]){
            prime.push_back(i);
            for(int j=i+i;j<maxn;j+=i){
                is_prime[j] = false;
            }
        }
    }
}
int func(int x){
    vector<int> cnt;
    for(int i=0;i<prime.size();i++){
        if(prime[i]>x)
            break;
        if(x%prime[i]==0){
            int t = 0;
            while(x%prime[i]==0){
                t++;
                x = x/prime[i];
            }
            cnt.push_back(t);
        }
    }
    if(x>1){
        cnt.push_back(1);
    }
    int ans = 1;
    for(int i=0;i<cnt.size();i++){
        ans *= cnt[i]+1;
    }
    return ans;
}
int main(){
    init();
    int n;
    while(cin >> n && n!=0 &&n!=EOF){
        while(n--){
            int m;
            cin >> m;
            cout << func(m) << endl;
        }
    }
    return 0;
}
posted @ 2021-01-03 17:12  吐司奶猫荷包蛋  阅读(140)  评论(0)    收藏  举报