题意:
最多约数问题:正整数x的约数是能整除x的正整数。正整数x 的约数个数记为div(x)。例如,1,2,5,10 都是正整数10 的约数,且div(10)=4。设a 和b 是2 个正整数,a≤b,找出a和b之间约数个数最多的数x及其最多约数个数。
思路:
- 以[a,b]区间的数为单位, 暴力依次找出[a,b]每个数的约数个数
- 以质因子为单位,搜索每个落在区间[a,b]的数的约数个数
第二种的基本思想是一个定理:
设数 x = a1p1 * a2p2 * a3p3 * a4p4 * … * anpn(a1, a2, a3…是质因子),那么x的约数个数为(p1+1) * (p2+1) * (p3+1) * … *(pn+1)。
暴力法
这个如果约数个数一样多,输出哪一个呢?
大的?还是小的?
由于循环次数太多了,小数可以使用这个方法,大数的话,计算太慢了。。。
#include<bits/stdc++.h>
using namespace std;
int main() {
int a,b;
cin>>a>>b;
int max=0,maxi=0;
for(int i=a; i<=b; i++) {
int t=0;
for(int j=1; j<=i; j++) {
if(i%j==0)
t++;
}
if(max<=t) {
max=t;
maxi=i;
}
}
printf("div(%d)=%d\n",maxi,max);
return 0;
}
改进版
#include<bits/stdc++.h>
using namespace std;
struct stu {
int n;
int num;
} stu[100];
int p=0;
int main() {
int a,b;
cin>>a>>b;
int max=0;
for(int i=a; i<=b; i++) {
int t=0;//t记录i的约数个数
for(int j=1; j<=i; j++) {
if(i%j==0)
t++;
}
//if(max<t)这个如果约数个数一样多,输出哪一个呢?
//例子:1 10 1 8 10和8和6的约数都是4且都是最大的
//最好的方法 当然是全部都输出
if(t>=max) {
if(t>max)
p=0;
max=t;
stu[p].n=i;
stu[p++].num=t;
}
}
for(int i=0; i<p; i++)
printf("div(%d)=%d\n",stu[i].n,stu[i].num);
return 0;
}
算法版
#include<bits/stdc++.h>
using namespace std;
struct stu {
int n;
int num;
} stu[100];
int t=0;
int p[10000];
//判断n是否是质因数
bool isprime(int n) {
for(int i=2; i<=sqrt(n); i++) {
if(n%i==0) {
return false;
}
}
return true;
}
//求n的约数的个数
int solve(int n) {
memset(p,0,sizeof(p));
int count=1;
int num=n;
if(num==1)//n==1只有一个约数
return 1;
if(isprime(num))//n是质数 只有1和本身2个约数
return 2;
for(int i=2; i<=(sqrt(num)+1); i++) { //分解质因子
if(n%i==0) {
p[i]++;
n/=i;
i--;还原i 质因子可能重复
}
}
for(int i=2; i<=num; i++) {
if(p[i])
count*=(p[i]+1);
}
return count;
}
int main() {
int a,b;
cin>>a>>b;
int max=0;
for(int i=a; i<=b; i++) {
int x=solve(i);
if(x>=max) {
if(x>max)
t=0;
stu[t].n=i;
stu[t++].num=x;
max=x;
}
}
for(int i=0; i<t; i++)
printf("div(%d)=%d\n",stu[i].n,stu[i].num);
return 0;
}
【】
#include<bits/stdc++.h>
using namespace std;
int p[10000];
//判断n是否是质因数
bool isprime(int n) {
for(int i=2; i<=sqrt(n); i++) {
if(n%i==0) {
return false;
}
}
return true;
}
//求n的约数的个数
int solve(int n) {
memset(p,0,sizeof(p));
int count=1;
int num=n;
if(num==1)//n==1只有一个约数
return 1;
if(isprime(num))//n是质数 只有1和本身2个约数
return 2;
for(int i=2; i<=num; i++) { //分解质因子
if(n%i==0) {
p[i]++;
n/=i;
i--;//还原i 质因子可能重复
}
}
for(int i=2; i<=num; i++) {
if(p[i])
count*=(p[i]+1);
}
return count;
}
int main() {
int a,b;
cin>>a>>b;
int max=0,maxi=0;
for(int i=a; i<=b; i++) {
int x=solve(i);
if(x>=max) {
max=x;
maxi=i;
}
}
printf("div(%d)=%d\n",maxi,max);
return 0;
}