求一个数的因子数问题常用的方法是试除法,代码如下:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
int main(){
int n;cin >> n;
vector<int> factor;
factor.push_back(1);
for(int i=2;i<=sqrt(n);++i){
if(n % i == 0){
factor.push_back(i);
if(n/i != i) factor.push_back(n/i);
}
}
if(n > 1) factor.push_back(n);
for(auto x:factor) cout << x << " ";
return 0;
}
一个数最多的因子数最多2×sqrt(n)个,这是上界,而在数据范围到2e9之前因子数最多的一个数也就1536个.这个是远小于上界的,所以我们可以改进一下算法.
根据唯一分解定理.一个数可以被分解为:p1k1×p2k2…pnkn这里的p都是质数.那一个数的因子其实就是这些质数不同次幂之间的组合,可以用搜索算法,一个一个枚举出来.就可以更快的计算出一个数的因子数了.
具体做法就是先进行质因数分解,然后dfs出答案.质因数分解的时候可以预处理出1-sqrt(n)的质数,加速这个过程.
代码
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
const int N = 1e6;
using namespace std;
bool vis[N];
vector<int> prime;
void get_prime(int n){
for(int i=2;i<=n;++i){
if(!vis[i]) prime.push_back(i);
for(auto x:prime){
if(x*i > n) break;
vis[x*i] = 1;
if(i % x == 0) break;
}
}
}
int tot,n;
vector<int> factor;
vector<pair<int,int>> prime_factor;
void dfs(int u,int cur){
if(u == tot){
factor.push_back(cur);
return;
}
int tmp = 1;
for(int i=0;i<=prime_factor[u].second;i++){
dfs(u+1,cur*tmp);
tmp *= prime_factor[u].first;
}
}
int main(){
cin >> n;
get_prime((int)sqrt(n));
for(int i=2;i<=sqrt(n);++i){
if(n%i == 0){
int num = 0;
while(n%i==0){
num++;
n/=i;
}
prime_factor.push_back(make_pair(i,num));
}
}
if(n > 1) prime_factor.push_back(make_pair(n,1));
tot = prime_factor.size();
dfs(0,1);
sort(factor.begin(),factor.end());
for(auto x:factor) cout << x << " ";
return 0;
}