欧拉#5项目;这个解决方案有效 - 但为什么
Project Euler # 5; this solution works - but why?
项目欧拉问题 5 表述为:"2520 是最小的数,可以除以 1 到 10 的每个数,没有任何余数。
被 1 到 20 的所有数字均匀整除的最小正数是多少?这是我正在使用的函数的 c++ 代码。
long long unsigned int rangeLCM(int n)
{
long long unsigned int ans=1;
for(int i=1;i<=n;i++)
{
if(ans%i!=0)
{
if(i%(ans%i)==0)ans*=(i/(ans%i));
else ans*=i;
}
}
return ans;
}
该代码适用于问题中所述的示例和问题本身{rangeLCM(10)=2520
和rangeLCM(20)=232792560
},但我认为它并不完美,并且错过了一些边缘情况。
我没有实际计算LCM(ans,i)
,而是检查了两者中较大的一个(总是ans
)可以被i
整除。如果不是,则ans
乘以等于 i/(ans%i)
或 i
的数字,具体取决于i
是否可以被 (ans%i)
整除。
这是基于以下事实:
LCM(8,12)=24=12*(8/(12%8));
LCM(9,30)=90=30*(9/(30%9)
LCM(7,13)=91=13*7
但是,对于以下类型的情况,它将失败:LCM(8,14)=56 != 8*14
然而,rangeLCM 的代码为我尝试过的所有输入提供了正确的输出。为什么?
你的逻辑不起作用
if(i%(ans%i)==0)ans*=(i/(ans%i));
else ans*=i;
例如,如果 ans = 10
和 i = 14
,则 lcm 应为 70,但在代码中为 140。
原因是,在 ans
和 i
之间,存在公共除数,但您的代码无法检测到。
为了进行实验,我写了一小段代码来使用 Java 进行检查。
class Solution {
public static void main(String[] args) {
long ans = 1;
for (long i = 1; i <= 40; i++) {
if (ans % i != 0) {
long before = (ans*i/gcd(ans,i));
if (i % (ans % i) == 0){
ans *= (i / (ans % i));
}else{
ans *= i;
}
System.out.println(ans + " " + before + " " + i);
}
}
}
public static long gcd(long a, long b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
}
输出
2 2 2
6 6 3
12 12 4
60 60 5
420 420 7
840 840 8
2520 2520 9
27720 27720 11
360360 360360 13
720720 720720 16
12252240 12252240 17
232792560 232792560 19
5354228880 5354228880 23
26771144400 26771144400 25
722820898800 80313433200 27
20961806065200 20961806065200 29
649815988021200 649815988021200 31
1299631976042400 1299631976042400 32
48086383113568800 48086383113568800 37
当 i = 27 时,正确答案和ans
lcm(a,b) 的公式为
lcm(a,b) = a*b/gcd(a,b)
与 gcd 是两个数字 a 和 b 之间的最大公约数
我认为您错过了很多情况,您必须在
if(i%(ans%i)==0)ans*=(i/(ans%i));
相关文章:
- 为什么是0;C++中的有效语句
- 为什么将值返回函数传递给重载=运算符对运算符函数有效,而对其他运算符无效
- 为什么这种直接初始化有效?(C++17)
- 为什么在引用指针时将 const 放在 & 符号的左侧有效,而在右侧则无效?
- 为什么浮点数的矢量化比双精度更有效?
- 为什么模板参数中的双冒号有效?
- 为什么在这种情况下递增阵列名称有效?
- 为什么TinyXML2的XMLDocument::FirstChild()函数在尝试解析这个有效的XML文件时返回NULL?
- 这是什么代码?为什么它有效?C++
- 为什么别名声明不是有效的 init 语句(/simple-declaration)?
- 为什么在 C/C++ 中交织 switch/for/if 语句是有效的?
- 为什么这个复合语句作为用大括号和括号括起来的语句序列似乎不是有效的语句表达式
- 为什么使用不匹配的参数调用重载函数仍然有效
- 通过指针调用模板类成员函数 [为什么这是有效的 c++]?
- 为什么此代码片段有效?如何取消引用空点?
- 为什么 lambda nullptr 取消引用在这种情况下有效?
- std::map::emplace无法解决,但插入右值有效 - 为什么?
- 当程序从该函数调谐器时,指向在函数中声明和定义的某些 C 字符串的指针不再有效.为什么?
- 将浮点数分配给字符串引用有效 - 为什么
- Unicode字符或多字节字符:哪种类型更有效?为什么