问题重述:
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?
问题的意思是找出可以整除小于等于某个数的所有公倍数,给出的测试用例是可以整除小于等于10的最小公倍数是2520,求
出可以整除小于等于20的最小公倍数(只针对正整数)。
思想:
先想一下如果不考虑计算时间,最简单的办法就是找出一个范围,让这个范围的数挨个对1~20内的数整除,但是问题就是
这个范围到底怎么找,一个简单的想法就是,最后的答案肯定小于20!,大于小于20所有素数的乘积。
想到这里我突然想起前面几个关于素数的问题,可不可以借助前面的想法呢?答案肯定是可以的。
先考虑这样一个问题2,3的最小公倍数是6,就是3和2的乘积;6和8的最小公倍数却是24,不是6和8的乘积,这里的问题出
在6和8有公因子,而2和3却没有,那么根据这个想法可以处理这个问题,假设现在有个数接近他的最小倍数,如果这个数是合数
那么可能这个数乘以他的因子就可以整除了。代码如下:
my solution is written by c++, work for any range! 1 #include <iostream> 2 #include <string> 3 #include <vector> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <math.h> 7 using namespace std; 8 9 10 int least_common_multiple(int num) 11 { 12 int common = 1;//初始化最小公倍数 13 for (int i = 2; i <= num; i++) 14 { 15 if(common % i != 0)//如果不能整除则说明里面有common要乘的因子 16 { 17 int temp = i; 18 for (int j = 2; j <= (int)sqrt(i); j++)//求素因子 19 { 20 if(temp % j == 0) 21 { 22 if((temp / j) == 1) 23 continue; 24 temp = temp / j; 25 j = 1;//如果找到一个因子,重置j 26 } 27 } 28 cout <<i << " "<< temp << endl;//打印出它每次要乘的因子 29 common *= temp;//公倍数乘以素数部分 30 } 31 } 32 33 return common; 34 } 35 36 37 int main(int argc, const char *argv[]) 38 { 39 int num = atoi(argv[1]); 40 cout << "num: "<<num << " " << (int)sqrt(8)<< endl; 41 cout << least_common_multiple(num) << endl; 42 return 0; 43 } if you want to use my solution. please delete line number before complie
这次程序的速度还是相当快的
当num为10,common为2520
当num为30,common为2329089562800
注意当num为30时,最小公倍数已经超出int类型的范围,建议使用long long int。