C#求解欧拉计划第5题:如何优化1-20最小公倍数求解代码?
欧拉计划第5题代码优化方案
你的代码逻辑是正确的,确实能得到结果,但可以从几个维度优化,提升效率和代码简洁性:
1. 缩小检查范围
能被11到20所有数整除的数,必然能被1到10的数整除(比如能被20整除就自动满足被2、4、5、10整除;能被18整除就满足被2、3、6、9整除)。所以循环条件只需要检查11到20的数即可,大幅简化条件表达式:
int i = 1; while (i % 11 != 0 || i % 12 != 0 || i % 13 != 0 || i % 14 != 0 || i % 15 != 0 || i % 16 != 0 || i % 17 != 0 || i % 18 != 0 || i % 19 != 0 || i % 20 != 0) { i++; }
2. 增大循环步长
目标数必然是20的倍数(因为要被20整除),所以不需要每次i++,可以直接以20为步长递增,减少循环次数:
int i = 20; // 从20开始,直接检查20的倍数 while (i % 11 != 0 || i % 12 != 0 || i % 13 != 0 || i % 14 != 0 || i % 15 != 0 || i % 16 != 0 || i % 17 != 0 || i % 18 != 0 || i % 19 != 0) { i += 20; }
注:这里可以去掉i%20!=0的判断,因为步长是20,i始终是20的倍数。
3. 数学方法:计算最小公倍数(最优解)
问题本质是求1到20的最小公倍数(LCM),这是效率最高的方式,不需要循环试错。
最小公倍数的计算可以通过质因数分解:取每个质数的最高次幂相乘:
- 2⁴(16)、3²(9)、5¹(5)、7¹(7)、11¹、13¹、17¹、19¹
相乘结果为:16×9×5×7×11×13×17×19 = 232792560
也可以用代码通过最大公约数(GCD)推导LCM(公式:LCM(a,b) = a*b / GCD(a,b)),迭代计算1到20的LCM:
long result = 1; for (int num = 2; num <= 20; num++) { result = LCM(result, num); } Console.WriteLine(result); // 计算最大公约数(欧几里得算法) long GCD(long a, long b) { while (b != 0) { long temp = b; b = a % b; a = temp; } return a; } // 计算最小公倍数 long LCM(long a, long b) { return a / GCD(a, b) * b; // 先除后乘避免溢出 }
注:这里用long类型是因为结果超出了int的范围(int最大值是2147483647),会导致溢出。
内容的提问来源于stack exchange,提问作者Deivydas
相关产品推荐
相关产品推荐

