利用(线性筛法O(n) + 算数基本定理) 基本上可以解决所有因子问题。
本文提供的方法:
1.计算任意数字的最小素因子
2.计算任意数字的最大素因子
3.计算任意数字的素因子种类数量
4.计算任意数字的因子个数
5.计算任意数字的因子和
1.计算任意数字的最小质因子
#include <stdio.h>
#define MAX_N 1000000
#define MIN(a,b) (a) > (b) ? (b):(a)
int prime[MAX_N + 5] = {0};
int dnum[MAX_N + 5] = {0};
void init(){
for (int i= 2; i <= MAX_N; ++i){
if (!prime[i]){
prime[++prime[0]] = i;
dnum[i] = i;
}
for (int j = 1; j <= prime[0]; ++j){
if (i * prime[j] >= MAX_N){
break;
}
prime[i * prime[j]] = 1;
dnum[i * prime[j]] = MIN(dnum[i],dnum[prime[j]]);
if (i % prime[j] == 0) break;
}
}
}
int main(){
int n;
init();
while (~scanf("%d", &n)){
printf("%d\n", dnum[n]);
}
return 0;
}
2.计算任意数字的最大质因子
#include <stdio.h>
#define MAX_N 1000000
#define MIN(a,b) (a) > (b) ? (b):(a)
#define MAX(a,b) (a) > (b) ? (a):(b)
int prime[MAX_N + 5] = {0};
int dnum[MAX_N + 5] = {0};
void init(){
for (int i= 2; i <= MAX_N; ++i){
if (!prime[i]){
prime[++prime[0]] = i;
dnum[i] = i;
}
for (int j = 1; j <= prime[0]; ++j){
if (i * prime[j] >= MAX_N){
break;
}
prime[i * prime[j]] = 1;
dnum[i * prime[j]] = dnum[i];
if (i % prime[j] == 0) {
break;
}
}
}
}
int main(){
int n;
init();
while (~scanf("%d", &n)){
printf("%d\n", dnum[n]);
}
return 0;
}
3.计算任意数字的质因子种类数量
#include <stdio.h>
#define MAX_N 1000000
#define MIN(a,b) (a) > (b) ? (b):(a)
#define MAX(a,b) (a) > (b) ? (a):(b)
int prime[MAX_N + 5] = {0};
int dnum[MAX_N + 5] = {0};
void init(){
for (int i= 2; i <= MAX_N; ++i){
if (!prime[i]){
prime[++prime[0]] = i;
dnum[i] = 1;
}
for (int j = 1; j <= prime[0]; ++j){
if (i * prime[j] >= MAX_N){
break;
}
prime[i * prime[j]] = 1;
dnum[i * prime[j]] = dnum[i] + (i % prime[j] != 0);
if (i % prime[j] == 0) {
break;
}
}
}
}
int main(){
int n;
init();
while (~scanf("%d", &n)){
printf("%d\n", dnum[n]);
}
return 0;
}
4.计算任意数字的因子个数
#include <stdio.h>
#define MAX_N 1000000
#define MIN(a,b) (a) > (b) ? (b):(a)
#define MAX(a,b) (a) > (b) ? (a):(b)
int prime[MAX_N + 5] = {0};
int dnum[MAX_N + 5] = {0};
void init(){
for (int i= 2; i <= MAX_N; ++i){
if (!prime[i]){
prime[++prime[0]] = i;
dnum[i] = 2;
}
for (int j = 1; j <= prime[0]; ++j){
if (i * prime[j] >= MAX_N){
break;
}
prime[i * prime[j]] = 1;
if (i % prime[j] == 0) {
int cnt = 0;
int temp = i;
while (temp % prime[j] == 0){
temp /= prime[j];
cnt++;
}
dnum[i * prime[j]] = dnum[i] / (cnt + 1) * (cnt + 2);
break;
}else{
dnum[i * prime[j]] = dnum[i] * dnum[prime[j]];
}
}
}
}
int main(){
int n;
init();
while (~scanf("%d", &n)){
printf("%d\n", dnum[n]);
}
return 0;
}
5.计算任意数字的因子和
#include <stdio.h>
#include <math.h>
#define MAX_N 1000000
#define MIN(a,b) (a) > (b) ? (b):(a)
#define MAX(a,b) (a) > (b) ? (a):(b)
int prime[MAX_N + 5] = {0};
int dnum[MAX_N + 5] = {0};
void init(){
dnum[1] = 1; ///初始值
for (int i= 2; i <= MAX_N; ++i){
if (!prime[i]){
prime[++prime[0]] = i;
dnum[i] = i + 1;
}
for (int j = 1; j <= prime[0]; ++j){
if (i * prime[j] >= MAX_N){
break;
}
prime[i * prime[j]] = 1;
if (i % prime[j] == 0) {
int temp = i;
int cnt = 0;
while (temp % prime[j] == 0){
cnt++;
temp /= prime[j];
}
dnum[i * prime[j]] = dnum[temp] * ((pow(prime[j], cnt + 2) - 1) / (prime[j] - 1));
break;
}else{
dnum[i * prime[j]] = dnum[i] * dnum[prime[j]];
}
}
}
}
int main(){
int n;
init();
while (~scanf("%d", &n)){
printf("%d\n", dnum[n]);
}
return 0;
}
PS:细心的同学可能会发现我的所有for都是++i,因为i++存在弹栈操作相对较慢一些。
PS2:代码格式很重要!