Problem 5 : Smallest multiple
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
1. 第5个问题 : 最小的倍数
2520是最小的数,可以被1到10的每一个数整除,没有任何余数。
可以被从1到20的所有数整除的最小的正数是什么?
2. 求解分析
这道题要求解能被几个数整除的最小数,其实就是求最小公倍数。要求解最小公倍数,我们就要知道最大公约数,因为最小公倍数 = 几个数的乘积 / 最大公约数。
所以,我们需要两个函数:一个函数求解最大公约数,另一个函数求解最小公倍数。
3. C++ 代码实现
类PE0005的方法getHighestCommonFactor()用最普通的方法来计算最大公约数。
类PE0005的方法getSmallestMultiple()来逐个计算当前的数和以前的数乘积的最小公倍数,最后计算出1到10或20的最小公倍数。
C++ 代码
#include <iostream>
#include <cmath> // sqrt()
#include <cassert> // assert()
using namespace std;
class PE0005
{
public:
int getHighestCommonFactor(int n, int m);
long getSmallestMultiple(int numbers);
};
int PE0005::getHighestCommonFactor(int n, int m) // gcd
{
double squareRoot = max(sqrt((double)n), sqrt((double)m));
for(int divisor=(int)squareRoot; divisor>=2; divisor--)
{
if (n % divisor == 0 && m % divisor == 0) // divisor is common factor
{
return divisor;
}
}
return 1;
}
long PE0005::getSmallestMultiple(int numbers)
{
int gcd;
long smallestNumber = 1;
for (int i=2; i<=numbers; i++)
{
gcd = getHighestCommonFactor(i, smallestNumber);
smallestNumber = smallestNumber/gcd * i;
}
return smallestNumber;
}
int main()
{
PE0005 pe0005;
assert(2520 == pe0005.getSmallestMultiple(10));
cout << pe0005.getSmallestMultiple(20) << " is the smallest number that can be ";
cout << "divided by each of the numbers from 1 to 20 without any remainder" << endl;
return 0;
}
4. Python 代码实现
Python跟C++实现方法类似,也包含两个函数: gcd()和getSmallestMultiple()。函数gcd()实现方法跟C++的函数getHighestCommonFactor()不一样,使用了递归方法来求解两个正整数的最大公约 数。
Python 代码
def gcd(a, b):
""" Compute the greatest common divisor of a and b."""
while b != 0:
(a, b) = (b, a % b)
return a
def getSmallestMultiple(number):
smallestNumber = 1
for n in range (2, number):
commonDivisor = gcd(n, smallestNumber)
smallestNumber = int(smallestNumber*n/commonDivisor)
return smallestNumber
def main():
assert 2520 == getSmallestMultiple(10)
print(getSmallestMultiple(20), "is the smallest number that can be divided");
print("by each of the numbers from 1 to 20 without any remainder");
if __name__ == '__main__':
main()