最多约数问题的算法

合集下载

最多约数问题

最多约数问题

最多约数问题答案解析与勘误分类:算法设计2013-01-17 16:22 234人阅读评论(0) 收藏举报剪枝最多约数问题递归算法问题描述:正整数x的约数是能整除x的正整数。

正整数x 的约数个数记为div(x)。

例如,1,2,5,10 都是正整数10 的约数,且div(10)=4。

设a 和b 是2 个正整数,a≤b,找出a和b之间约数个数最多的数x。

编程任务:对于给定的2个正整数a≤b,编程计算a 和b 之间约数个数最多的数。

数据输入:输入数据由文件名为input.txt的文本文件提供。

文件的第1 行有2 个正整数a和b。

结果输出:程序运行结束时,找到a 和b之间约数个数最多的那个数及最多约数个数。

测试数据:【只给出最多约数个数, time limit: 1s】问题分析下面的解析摘自网上一篇博客(来源/sarah_jieyu/article/details/6512030),标红部分是我自己添加上去的。

本题的要求是,求出一个给定区间内的含约数最多的整数。

首先明确一下如何求一个数的约数个数:若一个数N满足:N = A1N1 * A2N2 * A3N3* …… * Am Nm,则n的约数个数为(N1 + 1) (N2 + 1) (N3 + 1) …… (Nm + 1)。

这是可以用乘法原理证明的。

最浅显的算法是,枚举区间内的每个整数,统计它们的约数个数。

这个算法很容易实现,但是时间复杂度却相当高。

因为题目约定区间的最大宽度可以达到10^9的数量级,相当庞大。

因此,在极限规模时,时间是无法忍受的。

所以,我们需要尽量的优化时间。

分析一下枚举的过程就会发现,如果我们枚举到两个数n和m*n(m为一相对于n较大的质数),那么我们将重复计算n的约数两次。

据此,我们发现了枚举效率低的根本所在。

为了解决这一重复,我们可以选取另一种搜索方法——以质因子为对象进行深度搜索。

初始时,令number := 1,然后从最小的质数2开始枚举,枚举包含一个2、两个2……n 个2的情况……直至number * 2n大于区间的上限(max)。

小学奥数竞赛寻找最大公约数

小学奥数竞赛寻找最大公约数

小学奥数竞赛寻找最大公约数在小学奥数竞赛中,寻找最大公约数是一个常见的问题。

最大公约数(Greatest Common Divisor,简称GCD)是指两个或多个数中能够整除它们的最大的正整数。

在解决这类问题时,可以采取多种方法,如质因数分解、辗转相除法等。

本文将介绍奥数竞赛中常用的寻找最大公约数的方法,并举例说明。

一、质因数分解法质因数分解法是一种常用的寻找最大公约数的方法。

它通过将给定的数进行质因数分解,然后找到它们共有的质因数,最后将这些质因数相乘,得到最大公约数。

举例说明:假设我们要求解最大公约数的问题是:求26和39的最大公约数。

首先,我们对26和39进行质因数分解:26 = 2 × 1339 = 3 × 13可以看出,26和39的质因数分别为2、13和3、13,它们的公共质因数为13,因此,最大公约数为13。

二、辗转相除法辗转相除法,又称欧几里得算法。

它是一种通过用除数去除被除数,得到余数,然后将被除数赋值为除数,余数赋值为被除数,重复上述步骤直到余数为0的方法。

最终,被除数即为最大公约数。

举例说明:假设我们要求解最大公约数的问题是:求45和60的最大公约数。

首先,我们用60除以45,得到商1余15,即60 = 1 × 45 + 15。

然后,我们用45除以15,得到商3余0,即45 = 3 × 15 + 0。

因此,最大公约数为15。

三、更相减损术更相减损术是另一种常用的寻找最大公约数的方法。

它通过不断相减两个数中较大的数与较小的数,直到两个数相等或者差值为1,然后取相等值或者差值为1的那个数为最大公约数。

举例说明:假设我们要求解最大公约数的问题是:求72和96的最大公约数。

首先,我们用较大的数96减去较小的数72,得到差24。

然后,我们用较大的数72减去较小的数24,得到差48。

接着,我们用较大的数48减去较小的数24,得到差24。

最后,两个数相等,因此最大公约数为24。

最大公约数和最小公倍数的计算方法及应用

最大公约数和最小公倍数的计算方法及应用

最大公约数和最小公倍数的计算方法及应用在数学中,最大公约数和最小公倍数是一些基础概念。

学习这些概念能让学生更深入地理解数学的基础,并且这些计算方法也在一些实际问题中得到了应用。

最大公约数定义最大公约数,简称“gcd”,是指两个或多个整数中最大的能够整除它们的数,也就是说,是所有公约数中最大的一个数。

例如,两个数23和69的最大公约数就是1,两个数24和60的最大公约数就是12。

最小公倍数定义最小公倍数,简称“lcm”,是指两个或多个整数中最小的整数,能被这些整数整除。

也就是说,它是所有公倍数中最小的一个数。

例如,两个数6和15的最小公倍数是30,两个数8和24的最小公倍数是24。

最大公约数的求法我们来看看最大公约数的计算方法。

有多种方法可以计算两个数之间的最大公约数。

下面分别列出两个数的所有因数,并将它们的公共因子中的最大值找出来。

例如,24和36:1、24的因数是1, 2, 3, 4, 6, 8, 12, 24;2、36的因数是1, 2, 3, 4, 6, 9, 12, 18, 36。

它们共同的因数是1, 2, 3, 4, 6, 和12,最大公约数就是12。

这个方法称为“枚举法”。

另外,欧几里得算法也是一种常用的方法来求最大公约数。

这个方法从两个数中较小数进行减法,分别得到一系列新的数。

这些新数都是原来两个数的整除数。

最后两个数的最大公约数就是这些新数中的最大数。

例如,用这个方法计算24和36的最大公约数:1、用36去除24,得到12;2、用24去除12,余数是0;因此,36和24的最大公约数就是12。

最小公倍数的求法最小公倍数的计算方法也有很多种。

一种方法是首先将两个整数分解为它们各自的素因子,然后计算它们的公共素因子的乘积,再将剩下的部分乘起来。

例如,计算6和15的最小公倍数:1、6可以分解为2*3,15可以分解为3*5;2、两个数的公共素因子是3,乘积是3;3、不共有的部分2和5相乘,得到10。

十大数学算法

十大数学算法

十大数学算法数学算法是解决数学问题的方法和步骤的集合。

在数学领域中,有许多重要且被广泛使用的算法。

这些算法不仅能够解决各种数学问题,还在计算机科学、工程和其他领域中得到了广泛应用。

在本文中,我们将介绍十大数学算法,它们分别是欧几里得算法、牛顿法、二分法、高斯消元法、快速傅里叶变换、动态规划、贝叶斯定理、蒙特卡洛方法、线性规划和迭代法。

1. 欧几里得算法欧几里得算法是解决最大公约数问题的一种常见方法。

该算法的核心思想是,通过不断用较小数去除较大数,直到余数为零,最后一个非零余数即为最大公约数。

欧几里得算法在密码学、数据压缩等领域得到了广泛应用。

2. 牛顿法牛顿法是一种用来求解方程近似解的迭代方法。

它基于函数的泰勒级数展开,通过不断迭代逼近函数的零点。

牛顿法在优化问题、图像处理和物理模拟等领域中广泛使用。

3. 二分法二分法又称折半查找法,是一种高效的查找算法。

它通过将查找区间一分为二,判断目标元素在哪一侧,并重复此过程,直到找到目标元素或确认不存在。

二分法在查找有序列表和解决优化问题时被广泛应用。

4. 高斯消元法高斯消元法是一种求解线性方程组的常用方法。

它通过对方程组进行一系列的行变换,将方程组化为简化的阶梯形式,从而求得方程组的解。

高斯消元法在计算机图形学、物理学和工程学等领域中得到广泛应用。

5. 快速傅里叶变换快速傅里叶变换是一种计算离散傅里叶变换的高效算法。

通过将离散信号转换为频域信号,可以在数字信号处理、图像处理和通信系统中实现快速算法和压缩方法。

6. 动态规划动态规划是一种解决具有重叠子问题和最优子结构性质的问题的算法。

通过将问题分解为子问题,并保存子问题的解,动态规划可以高效地求解一些复杂的优化问题,如最短路径、背包问题和序列比对等。

7. 贝叶斯定理贝叶斯定理是一种用来计算条件概率的方法。

它通过已知先验概率和观测数据来更新事件的后验概率。

贝叶斯定理在机器学习、人工智能和统计推断等领域中具有重要的应用。

求最大公约数的方法

求最大公约数的方法

求最大公约数的方法最大公约数,简称最大公因数,是指两个或多个整数共有约数中最大的一个。

在数学中,求最大公约数是一个常见的问题,它在数论、代数等领域都有着重要的应用。

下面我们将介绍几种常见的求最大公约数的方法。

1. 辗转相除法。

辗转相除法,又称欧几里德算法,是一种求最大公约数的有效方法。

它的原理是利用两个整数的除法运算,不断地用较小的数去除较大的数,然后用余数替换原来的除数,直到余数为0为止。

最后的除数就是这两个整数的最大公约数。

例如,我们要求出36和48的最大公约数。

首先用48除以36,得到商1余数12,然后用36除以12,得到商3余数0。

因此,36和48的最大公约数为12。

2. 穷举法。

穷举法是一种直观的求最大公约数的方法。

它的原理是列举出两个整数的所有约数,然后找出它们的公共约数中最大的一个。

以24和36为例,首先列举出24的约数,1,2,3,4,6,8,12,24;然后列举出36的约数,1,2,3,4,6,9,12,18,36。

最后找出它们的公共约数,1,2,3,4,6,12,其中最大的是12,因此24和36的最大公约数为12。

3. 质因数分解法。

质因数分解法是一种基于质因数分解的求最大公约数的方法。

它的原理是将两个整数分别进行质因数分解,然后找出它们共有的质因数,再将这些质因数相乘即可得到它们的最大公约数。

以60和84为例,首先将它们分别进行质因数分解,60=2^235,84=2^237。

然后找出它们共有的质因数,2^2和3,再将它们相乘得到12,因此60和84的最大公约数为12。

4. 更相减损术。

更相减损术是一种古老的求最大公约数的方法。

它的原理是用较大的数减去较小的数,然后用得到的差替换原来的较大数,如此循环直到两数相等为止。

最后的相等数就是这两个整数的最大公约数。

以126和84为例,首先用较大的数126减去较小的数84,得到42,然后用84减去42得到42,最后42减去42得到0。

最大公约数和最小公倍数的计算方法

最大公约数和最小公倍数的计算方法

最大公约数和最小公倍数的计算方法在数学中,最大公约数和最小公倍数是两个常用的概念。

最大公约数是指两个或多个整数共有约数中的最大值,而最小公倍数则是指两个或多个整数公有倍数中的最小值。

计算最大公约数和最小公倍数是解决数学问题和简化计算的重要方法。

本文将介绍几种常见的计算方法。

一、辗转相除法辗转相除法,也被称为欧几里德算法,是一种求解两个数的最大公约数的有效方法。

该方法基于以下原理:若两个整数a和b (a > b),将a除以b得到商q和余数r,若r等于0,则b即为最大公约数;若r不等于0,则将b当作新的a,将r当作新的b,继续进行相同的操作,直到余数为0。

示例如下:假设我们要求解26和15的最大公约数。

1. 26 ÷ 15 = 1 余 112. 15 ÷ 11 = 1 余 43. 11 ÷ 4 = 2 余 34. 4 ÷ 3 = 1 余 15. 3 ÷ 1 = 3 余 0因此,26和15的最大公约数为1。

同时,最小公倍数可以通过最大公约数求解。

根据最大公约数的性质,设两个整数a和b,其最大公约数为g,最小公倍数为l,则有以下公式:l = (a × b) / g因此,使用辗转相除法求得最大公约数后,即可计算出最小公倍数。

二、质因数分解法质因数分解法是通过将整数分解为质数的乘积形式,求解最大公约数和最小公倍数。

具体步骤如下:1. 将待求解的两个整数分别进行质因数分解。

2. 将两个整数的质因数列出,并按照次数较高的相同质因数写成乘积的形式。

3. 最大公约数为两个整数所有相同质因数的最小次数相乘的乘积。

4. 最小公倍数为两个整数所有质因数的最大次数相乘的乘积。

例如,我们求解36和48的最大公约数和最小公倍数。

1. 36的质因数分解为2^2 × 3^2。

2. 48的质因数分解为2^4 × 3^1。

3. 最大公约数为2^2 × 3^1 = 12。

最大公约数与最小公倍数

最大公约数与最小公倍数

最大公约数与最小公倍数最大公约数和最小公倍数是数学中常见的概念,用于计算两个或多个数的公共因数和公共倍数。

本文将详细介绍最大公约数和最小公倍数的定义、计算方法以及它们在实际问题中的应用。

一、最大公约数(Greatest Common Divisor,简称GCD)最大公约数指的是两个或多个数中能够同时整除的最大的正整数。

在计算最大公约数时,我们常用到欧几里得算法。

这个算法基于一个简单的原理:两个整数的最大公约数等于其中较小数和两数相除余数的最大公约数。

例如,如果要计算30和45的最大公约数,首先用较大的数除以较小的数:45 ÷ 30 = 1 余 15然后将较小的数(30)与余数(15)进行计算:30 ÷ 15 = 2 余 0余数为0时,计算结束。

此时,最大公约数为较小的数(15)。

当涉及到多个数的最大公约数计算时,可以逐一计算两个数的最大公约数,得到的结果再与下一个数计算最大公约数,以此类推直到最后一个数。

最大公约数在实际问题中常用于简化分数、约简比例以及计算整数倍等方面。

它也是许多算法和数学问题的重要组成部分。

二、最小公倍数(Least Common Multiple,简称LCM)最小公倍数指的是两个或多个数中能够被它们同时整除的最小正整数。

计算最小公倍数时,我们可以使用最大公约数来简化计算。

最小公倍数可以通过以下公式计算得到:最小公倍数 = 两数的乘积 / 最大公约数例如,如果要计算12和15的最小公倍数,首先计算它们的最大公约数:12的因数为1、2、3、4、6、1215的因数为1、3、5、15可以看出,它们的最大公约数为3。

然后,将两个数的乘积除以最大公约数得到最小公倍数:(12 × 15)÷ 3 = 60因此,12和15的最小公倍数为60。

最小公倍数在实际问题中常用于解决时间、速度、周期等相关计算。

例如,计算两个车辆同时从起点出发,分别以不同速度绕圈行进,要求它们再次同时回到起点的最短时间,即可使用最小公倍数来得到答案。

数字的最大公约数

数字的最大公约数

数字的最大公约数数字的最大公约数(Greatest Common Divisor,简称GCD)是指一组数字中最大的能够同时整除所有数字的正整数。

在数学中,寻找数字的最大公约数是一个常见的问题,它有着广泛的应用领域,包括数论、代数学以及计算机科学等等。

本文将介绍数字的最大公约数的定义、计算方法以及一些常见问题的解答。

一、定义数字的最大公约数是指能够同时整除一组数字中的所有数字的最大正整数。

对于给定的数字 a 和 b,它们的最大公约数记为 gcd(a, b)。

最大公约数满足以下性质:1. gcd(a, b) = gcd(b, a),即最大公约数的顺序无关紧要;2. gcd(a, b) = gcd(b, a mod b),其中 mod 表示取余运算;3. gcd(a, 0) = a,即任何数字和0的最大公约数都是它自身。

二、计算方法1. 辗转相除法辗转相除法(Euclidean algorithm)是一种常用且高效的计算最大公约数的方法。

该方法基于 gcd(a, b) = gcd(b, a mod b) 的性质,通过不断取两个数的余数来逐步减小数字的范围,直到找到最大公约数。

具体步骤如下:- 给定两个数字 a 和 b;- 计算它们的余数 r = a mod b;- 若 r = 0,则 b 即为最大公约数;- 若r ≠ 0,则令 a = b,b = r,并重复上述步骤。

2. 最大公约数的性质和二进制运算最大公约数有一系列有趣的性质,其中之一是通过二进制运算来计算最大公约数。

这种方法被称为二进制法或 Stein 算法。

具体步骤如下:- 若 a 和 b 都为偶数,则 gcd(a, b) = 2 * gcd(a/2, b/2),即将两个数同时除以2并将结果乘以2;- 若 a 是偶数,b 是奇数,则 gcd(a, b) = gcd(a/2, b);- 若 a 是奇数,b 是偶数,则 gcd(a, b) = gcd(a, b/2);- 若 a 和 b 都是奇数,则 gcd(a, b) = gcd((a-b)/2, b)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

if (*p>up) return;
//质数大于上界,返回
else {
curPri=*p;
divLow=low-1;
divUp=up;
cur_num=curNum;
三、算法思想
count=curCount;
calPrimeCount=1;
while (1){
//枚举质因子个数
calPrimeCount++;
生成质数表的GenPrimes函数只计算一次,故其时间复杂度可忽略。递归 部分的程序为了减少不必要的计算,存在许多短跳的行为,其时间复杂性难以计算, 故以三种程序的运行实测结果进行比较。
输入 单次运算时间
时间复杂性
枚举全部整数法
1,10 0000 58秒
O(n2)
改进的枚举法
枚举质数法
1,10 0000 0.4秒

} int LeftPosCount=maxCount>>calPrimeCount;
优化4
if (curCount<LeftPosCount){
return;
//约数个数无法超过当前最大值
}
}
}
}
Part c.main函数
三、算法思想
void main()
{
ifstream fin(“input.txt”);
if ((curNum>=lowB) && (curCount>maxCount)){
maxCount= curCount;
maxLocate= curNum; }
优化1
p=primes+(curPrime-1);
for (int i=curPrime;i<=primeCount;i++,p++){ //对质数进行枚举
count+=curCount;
divLow=divLow/curPri; divUp=divUp/curPri;
优化2
if (divLow==divUp){ //质数不会落在搜索区间内 break;
优化3
} cur_num=cur_num*curPri;
优化2
Iterative(primes,i+1,cur_num,count,divLow+1,divUp);//搜索下一
✓利用以上规律,用枚举质数的指数的方法,可以编程求出
Antiprime数及其约数个数,运算速度极快
对应于本题,仅适用于a,b之间存在AntiPrime数的情况
(例如a,b间存在ap1,则最多约数是ap1的约数数);如果
a,b间不存在AntiPrime数(例如下图中ap1不存在,只存在
ap2),则还要用常规的枚举方法
}
✓大大减少了枚举运算的次数
时间复杂性达不到要求
被枚举的待求约数的数 56
a
b
二、解题过程
B.求AntiPrime法
AntiPrime数:如果一个自然数n,满足所有小于n的自然数的约数个 数都小于n的约数个数,则n是一个Antiprime数。譬如:1, 2, 4, 6, 12, 24,……。
性质:n=2k1·3k2·5k3·7k4·11K5….. 其中k1≥k2 ≥ k3 ≥ k4 ≥ k5… 约数个数:sum=(k1+1)(k2+1)(k3+1)(k4+1)(k5+1)…
《最多约数问题》解题报告
叶梁 2006
一、题目内容
问题描述
正整数x 的约数是能整除x 的正整数。正整数x 的约数个数记为 div(x)。例如,1,2,5,10 都是正整数10 的约数,且div(10)=4。设a 和b 是2 个正整数,a≤b,找出a 和b之间约数个数最多的数x。
编程任务
对于给定的2 个正整数a≤b,编程计算a 和b 之间约数个数最多的数。
fin>>lowB>>upB;
//输入
fin.close();
int Primes[primeCount];
GenPrimes(&Primes[0]);
//调用函数,生成质数表
if (lowB+upB==2) {
maxCount= 1;
//a,b均等于1的特例,返回1
}
else {
maxCount= 2;
2 分析数学规律获得程序优化途径:算法重点研究的最坏情况下的时间复杂 与空间复杂性,都是属于极限的情况,所以要从尽可能多的途径进行程序 的优化。优化的主要途径:一是尽量减少或消除程序的重复计算(题中优 化1、2),二是避免不必要的多余计算(题中优化3、4)。
✓达到题目要求
三、算法思想
Part a.求素数表(源程序请见.cpp)
Eratosthenes筛法 ·long int可表达的正整数是232-1,因此要用到的最到素数<sqrt(232)=65536
·定义数组int ArrInt[65536],并将各单元的初值赋为1 ·将指针*p,定位在ArrInt[2],若单元值为1,则使指针每次前进2个长度单位, 将该地址内容置0,直至到达数组上界。再将指针移回ArrInt[3],若单元值为1, 指针每次前进3个长度单位,将该地址内容置0…,直到全部循环完毕 ·剩下的未被置0(未被筛除)的单元所对应的在数组中的序号,即为素数 ·为使用方便,将素数写入数组Primes
内容 数组单元
3
3
2
2
2
2
数组ArrInt
1
1
1
1
0
1
0
1
0
0
0
1…
0
1
2
3
4
5
6
7
8
9 10 11 …
内容 数组单元
数组Primes
235 012
7 11 13 17 19 23 29 31 37 …
3
4
5
6
7
8
9 10 11 …
Part b.递归过程体
三、算法思想
void Iterative(int *primes,int curPrime,int curNum,int curCount,int
int Divi (int m){ int num=0; for (int j=1;j<=m;j++){ if (m%j==0) num++; } return(num);
} void main(){
int a,b; scanf("%d %d",&a,&b); int max=1,dn=0; for (int i=a;i<=b;i++){
ap2
ap1
0
a
b
C.枚举质数法
对常规枚举法的优化措施
二、解题过程
➢只用质数进行枚举(优化1) ➢利用约数通常是成对出现,搜索边界可以根据情况调整的规律 (优化2) ➢对不会落在区间内的数中断枚举(优化3) ➢对不可能达到当前最大约数的情况,中断枚举(优化4)
以上优化措施的落实见以下递归法中的标志。总而言之,尽可 能地减少运算次数,重点关注多重循环和递归体内的程序块。
O(n1.5)
1,21 0000 0000 0.17秒
•空间复杂性
程序的质数表Primes共有6542个数组长整形元素;递归部分最深可达6542层, 形参+局部变量共有14个长整形变量;全局变量忽略不计:估算运算过程中数据 占用内存量最高在384K左右,加上程序要400多K。
五、体会
1 用数学方法分析题意得到解题思路:通过课程内容和两次作业,可以体会 到数学在算法上占有非常重要的位置,只有从数学上获得解决问题的思路 才使编程成为可能。
dn=Divi(i); if (dn>max)max=dn;} printf("%d ",max); } 枚举的约数 Sqrt(56)
01 2 3 45 678 9
二、解题过程
•优化
int Divi (int m){ if (m==1) return 1; int num=0, j; //for (j=2;j<=m/j;j++){ int k=sqrt(m); for (j=2;j<=k;j++){ if (m%j==0) num+=2; } if (k*k==m) return (num+1); else return(num+2);
//非a,b均等于1的情况下,约数个数至少为2
Iterative(&Primes[0],1, 1, 1, lowB, upB); //递归求得最多约数个数
}
ofstream fout(“output.txt”);
fout<<maxCount;
//输出
fout.close();
}
•时间复杂性
四、时间空间复杂性
数据输入
输入数据由文件名为input.txt的文本文件提供。文件的第1 行有2 个 正整数a和b。
结果输出
程序运行结束时,若找到的a 和b 之间约数个数最多的数是x,将 div(x)输出到文件output.txt中。
输入文件示例
输出文件示例
input36
9
A.常规枚举法
low,int up){
int divLow,divUp,cur_num,calPrimeCount,curPri,count;
int *p;
//比较当前约数的个数,更新全局变量中的记录 if ((curNum<up) && (curCount*2>maxCount))
相关文档
最新文档