C 欧拉项目练习5方法
问题:2520是可以被1到10之间的每个数字除的最小数,没有余数 能被1到20的所有数整除的最小正数是多少 所以,我试着在ProjectEuler上做练习5,我得出了以下代码:C 欧拉项目练习5方法,c,C,问题:2520是可以被1到10之间的每个数字除的最小数,没有余数 能被1到20的所有数整除的最小正数是多少 所以,我试着在ProjectEuler上做练习5,我得出了以下代码: #include <stdio.h> #define TRUE 1 #define FALSE 0 int main () { int n, fnd = FALSE, count, i; for (i = 1; fnd == FALSE; i++) { count
#include <stdio.h>
#define TRUE 1
#define FALSE 0
int main () {
int n, fnd = FALSE, count, i;
for (i = 1; fnd == FALSE; i++) {
count = 0;
for (n = 1; n <= 20; n++) {
count += i % n;
}
printf ("testing %d, count was: %d\n", i, count);
if (count == 0) {
fnd = TRUE;
printf ("%d\n", i);
}
}
return 0;
}
#包括
#定义真1
#定义FALSE 0
int main(){
int n,fnd=FALSE,count,i;
对于(i=1;fnd==FALSE;i++){
计数=0;
对于(n=1;n您的方法花费的时间太长,因为这是一个蛮力解决方案。您需要稍微聪明一点
我给你的提示是:一个数被另一个数整除意味着什么?或者低于某个数的每一个数?这些数的素数因子是否有共性?这应该是一个很好的起点。提示:你应该查找“最小公倍数”
下一个提示:
答案是数字1、2、3、…、20的最小公倍数(LCM)
n个数字的LCM可以按顺序找到:如果LCM(1,2)=x,则LCM(1,2,3)=LCM(x,3);如果LCM(1,2,3)=y,则LCM(1,2,3,4)=LCM(y,4)等。因此,知道如何找到任意2个数字的LCM就足够了
为了找到两个数的LCM,我们可以使用以下公式:LCM(p,q)=pq/GCD(p,q),其中GCD是最大公因数
为了找到GCD,有一个著名的欧几里德算法(可能是地球上第一个非平凡算法)
我认为你应该从计算每个数的素数因子开始,从2到20。
由于所需的数字应该可以被1到20之间的每个数字整除,因此它还必须
可以被这些数字的每个素数因子整除
此外,跟踪主要因素的多样性也很重要。
例如,4=2*2,因此所需的数字必须能被2*2整除。我用Python 3快速制作的东西:
primary_list = []
for i in range(2, 4097):
j = i
k = 2
delta_list = primary_list[0:]
alpha_list = []
while j > 1:
if j % k == 0:
j /= k
alpha_list.append(k)
k = 2
else:
k += 1
for i in alpha_list:
try:
delta_list.remove(i)
except:
primary_list.append(i)
final_number = 1
for i in primary_list:
final_number *= i
print(final_number)
在一台速度很慢的机器下,只需几秒钟就可以完成计算。Python非常擅长抽象数字。这是完成这项工作的最佳工具
算法相对简单。我们有一个基本列表primary_list,在那里我们存储数字的倍数。然后是一个循环,我们估计我们要计算的数字的范围。我们使用一个临时变量j作为一个容易分割、切碎和征服的数字。我们使用k作为除数,从2开始。delta_列表是主_列表的主要工作副本,我们将一个数字接一个数字分开,直到只剩下所需的“逻辑”。然后我们将这些数字添加到主列表中
1:1
2:21
3:31
4:221
5:51
6:23 1
7:71
8:2221
9:331
10:25 1
最后一个数字是将我们在主\u列表中的数字相乘得出的
1*2*3*2*5*7*2*3=2520
如前所述,Python非常擅长数字。它是这项工作的最佳工具。这就是为什么你应该使用它来代替C、Erlang、Go、D或任何其他动态/静态语言来进行Euler练习的原因。我用C解决了它。下面是算法
#include <stdio.h>
#include <stdio.h>
int main()
{
int i;
int count;
for(i=21;i>0;i++)
{ count = 0;
for( int j=2;j<21;j++)
{
if (i%j!=0)
break;
count++;
}
if (count==19)
break;
}
printf("%d\n",i);
return 0;
}
#包括
#包括
int main()
{
int i;
整数计数;
对于(i=21;i>0;i++)
{count=0;
对于(int j=2;j只是对上述评论的一些想法
@pg190你说“它实际上只需要被1到20之间的素数整除,即2,3,5,7,11,13,17,19。”
取9699690,不偏离1-20之间的所有值
所以这可能是一个很好的解决方案
给定数字集[1-20]
最小公倍数的计算如下所示
例如,对于数字2、6、9
用素数乘法表示它们
2.2
6 2 3
9 3 3
LCM=每个素数的最高幂的倍数。
=2*3^2=18
这可以通过将每个数字表示为素数乘法来解决手头的问题
然后做这个数学题
$num=20;
for($j=19;$j>1;$j--)
{
$num= lcm($j,$num);
}
echo $num;
function lcm($num1, $num2)
{
$lcm = ($num1*$num2)/(gcd($num1,$num2));
return $lcm;
}
function gcd($n1,$n2)
{
$gcd=1;
$min=$n1;
if($n1>$n2)
{
$min=$n2;
}
for($i=$min;$i>1;$i--)
{
if($n1%$i==0 && $n2%$i==0)
{
$gcd*=$i;
$n1/=$i;
$n2/=$i;
}
}
return $gcd;
}
用php解决抱歉,刚刚编辑了这个问题。谢谢,现在更好了,但在下一个循环中,它将再次为零,如果每个数字的剩余部分除以1到20的和等于0,那么在结束循环后,它仍然为零。我做了一些研究,仍然无法找到答案。我是根据你和其他人做的ers的建议!谢谢!(我编辑了问题并解释了我最终是如何做到的)嗯……这有点令人尴尬,但我没有很好的数学背景……如果你能简化基础的话……不要尴尬,许多优秀的程序员都在为数学的更纯粹分支而挣扎。你需要探究这个问题的基本要点是,一个数要被1-20之间的每个数整除,它实际上只需要被I整除1和20之间的素数,即2,3,5,7,11,13,17,19。这是因为1和20之间的每一个数字都可以写成小于或等于自身的素数的乘积。所以取10,你可以写成2*5.15,3*5.16,2*2*2*2。插入另一个注释:那么你要找的数字看起来是这样的:(2^a)*(3^b)*(5^c)*(7^d)*(11^e)*(13^f)*(17^g)*(19^h)。不要被这里的符号吓倒,它只是意味着你需要搜索指数,而不是每个数字。我是根据你和其他人的建议做的!谢谢!(我编辑了问题并解释了我最终是如何做的)
$num=20;
for($j=19;$j>1;$j--)
{
$num= lcm($j,$num);
}
echo $num;
function lcm($num1, $num2)
{
$lcm = ($num1*$num2)/(gcd($num1,$num2));
return $lcm;
}
function gcd($n1,$n2)
{
$gcd=1;
$min=$n1;
if($n1>$n2)
{
$min=$n2;
}
for($i=$min;$i>1;$i--)
{
if($n1%$i==0 && $n2%$i==0)
{
$gcd*=$i;
$n1/=$i;
$n2/=$i;
}
}
return $gcd;
}