1. 程式人生 > 實用技巧 >牛客網計算機考研複試-KY3-約數的個數

牛客網計算機考研複試-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;
}