最大约数问题

rzzat1478 2009-09-22 10:26:25
问题描述: 正整数x的约数是能整除x的正整数。正整数x 的约数个数记为div(x)。例如,1,2,5,10 都是正整数10 的约数,且div(10)=4。设a 和b 是2 个正整数,a≤b,找出a和b之间约数个数最多的数x。
原理:设正整数x的质因子分解为x=p1^N1 × p2^N2 ×……pi^Ni则 div(x)=(N1+1)(N2+1)……(Ni+1)
书上代码如下,不过search函数看不懂,谁能帮忙解释下(最好一步步说明),谢谢。
#include<iostream>
using namespace std;

const int MAXP=1000;
int maxnum,numb; //maxnum存放最多约数个数,numb存放约数个数最多的数
int pCOUNT; //质数个数
int prim[MAXP]; //质数表

void primes() //产生质数
{
bool get[MAXP+1];
for(int i=2;i<=MAXP;i++)get[i]=true;
for(int i=2;i<+MAXP;i++)
{
if(get[i])
{
int j=i+i;
while(j<=MAXP){ get[j]=false;j+=i; }
}
}
int ii,j;
for(ii=2,j=0;ii<=MAXP;ii++)
if(get[ii])prim[++j]=ii;
pCOUNT=j;
}

void search(int from,int tot,int num,int low,int up) //搜索最多约数
{
if(num>=1)
if((tot>maxnum)||((tot==maxnum)&&(num<numb)))
{ maxnum=tot; numb=num; }
if((low==up)&&(low>num))search(from,tot*2,num*low,1,1);
for(int i=from;i<=pCOUNT;i++)
{
if(prim[i]>up)return;
else
{
int j=prim[i],x=low-1,y=up,n=num,t=tot,m=1;
while(true)
{
m++;t+=tot;x/=j;y/=j;
if(x ==y)break;
n*=j;
search(i+1,t,n,x+1,y);
}
m=1<<m;
if(tot<maxnum/m)return;
}
}
}

int main()
{
primes();
int low,up;
cin>>low>>up;
if((low==1)&&(up==1))
{ maxnum=1; numb=1; }
else
{ maxnum=2;numb=1;search(1,1,1,low,up); }
cout<<maxnum<<endl;
return 0;
}
谢谢了
...全文
358 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
贝隆 2009-10-06
  • 打赏
  • 举报
回复
学习
booksoon 2009-10-06
  • 打赏
  • 举报
回复
如果考虑a,b均为大整数(比如512位,1024位)?我想上面的程序没有一个能跑起来~~~
zeroieme 2009-10-06
  • 打赏
  • 举报
回复
提取质因数组合相乘才是正道
dichyzhu 2009-10-06
  • 打赏
  • 举报
回复

package test;

import java.util.HashMap;
import java.util.Map;

public class DivisorTest {
static Map<Integer, Integer> map;

static void search(int from, int to) {
map = new HashMap<Integer, Integer>();
for (int i = from; i <= to; i++) {
map.put(i, countCommonDivisor(i));
}
}

static int countCommonDivisor(int number) {
int count = 2;
for (int i = 2; i <= (number / 2); i++) {
if (number % i == 0) {
count++;
}
}
return count;
}

public static void main(String[] args) {
search(10, 100);
System.out.println(map);
int key = 0, value = 0;
for (Map.Entry<Integer, Integer> iter : map.entrySet()) {
if (value < iter.getValue()) {
key = iter.getKey();
value = iter.getValue();
}

}
System.out.println("Number=" + key + ",the number of max divisor is " + value);
}
}

hanyingmenghuan 2009-10-06
  • 打赏
  • 举报
回复
学习学习
arong1234 2009-10-06
  • 打赏
  • 举报
回复

const int MAXP = 10000;//最多的质数个数
unsigned int primes[MAXP];//质数表
int countOfPrimes=0;
void fillPrime()
{//填满质数表:
primes[0] = 2;
primes[1] = 3;
for(countOfPrimes = 2 ; countOfPrimes< MAXP; countOfPrimes++)
{
primes[pos] = nextPrime(primes[countOfPrimes-1]);
}
}
bool isPrime(unsigned int prime)
{
int pos;
for(pos = 0 ; pos < countOfPrimes ; pos ++)
{
if(0 == prime%primes[pos]) return false;
}
return true;
}
unsigned int nextPrime(unsigned int prime)
{
do {
prime += 2;
} while(!isPrime(prime));
return prime;
};

int div(int x)
{
int divx = 1;
for(int pos = 0 ; pos < countOfPrimes && x > primes[pos] * primes[pos]; pos ++)
{
unsigned int & prime = primes[pos];
if(x%prime) continue;
int count = 0;
while(0==x%prime) {
x = x/ prime;
count ++;
}
divx *= (1+count);
}
return divx;
}
int search(int from, int to)
{
int max = div(from);
int maxn = from;
for(int i=from+1; i < to; i++)
{
int divx = div(i);
if(divx > max) {
max = divx;
maxn = i;
}
}
return maxn;
}
  • 打赏
  • 举报
回复
楼主看看这个,简单明了
#include <iostream>
using namespace std;
int max_gys(int x,int y)
{
if(x==y)
return x;
else
return max_gys(abs(x-y),x);
}
int main()
{
int a;
a=max_gys(63,9);
cout<<a;
return 0;
}
oassuperhan 2009-09-23
  • 打赏
  • 举报
回复
其实感觉这个算法时间复杂度不低啊,如果是我绝不使用他的算法
oassuperhan 2009-09-23
  • 打赏
  • 举报
回复
这个可不是求最大公约数的问题,应该是“最多约数”问题
函数primes()作用是筛法求质数表1至MAXP的所有质数,解释略
search()是关键,low,up分别是问题中的最小值a和最大值b
主函数里的分析
if((low==1)&&(up==1))
{ maxnum=1; numb=1; }//这是特殊情况讨论,解释略
else
{ maxnum=2;numb=1;search(1,1,1,low,up); } //maxnum=2是指1和它本身两个数


search()是个递归函数
if(num>=1)
if((tot>maxnum)||((tot==maxnum)&&(num <numb)))
{ maxnum=tot; numb=num; }
//tot是当前搜索数的约数个数,如果大于maxnum,则代替其值
后面的实在没心情看下去了,太乱了~~~~~~
rzzat1478 2009-09-23
  • 打赏
  • 举报
回复
我错了,标题发错了,是求最多约数
fire_woods 2009-09-23
  • 打赏
  • 举报
回复
这个递归太狠了,感觉不如直接循环做有效率.
linren 2009-09-23
  • 打赏
  • 举报
回复
最大公约数可以使用欧几里得的辗转相除法来计算
hua_zhixing_ 2009-09-23
  • 打赏
  • 举报
回复
只是求最大约数,有必要搞得这么复杂吗?
rzzat1478 2009-09-22
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 surreyailing 的回复:]
哥们儿,你的程序注释真少啊!
[/Quote]
这是书上的,就是因为没有注释我才看不懂的~~
surreyailing 2009-09-22
  • 打赏
  • 举报
回复
哥们儿,你的程序注释真少啊!

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧