低于1000的3或5的所有倍数之和在C

时间:2018-07-25 06:28:59

标签: c

欧拉项目问题:

  

如果我们列出10下所有3 or 5的自然数,则得到3, 5, 6 and 9。这些倍数的总和是23

     

找到3 or 5下面的1000的所有倍数之和。

我的C代码:

long int x;

long int y;

long int z = 0;

long int a = 0;

long int b = 0;

for(x= 0; x < 1000; x += 3)  
    a = a + x;

for(y = 0; y < 1000; y += 5)  
    b = b + y;

z = a + b;
printf("%lu", z);

return 0;

但是我得到266333作为输出,这是错误的。我用Python检查了答案,并弄对了。我想知道我在用C代码做错什么。正确的答案是233168

我的Python代码:

print(sum(x for x in range(1000) if x % 3 == 0 or x % 5 == 0))

7 个答案:

答案 0 :(得分:8)

某些数字将被3和5整除,您不应将它们相加两次。 这样的代码将给出正确的结果:

long int x,total = 0;

for(x = 0; x < 1000; ++x)
{
    if(x % 3 == 0)
        total = total + x;
    else if(x % 5 == 0)
        total = total + x;
}

printf("%ld", total);

if else if上方的代码中,请确保数字被3或5整除。并允许在此基础上求和。

可以进一步优化为:

for(x= 0; x < 1000; ++x)
{
    if(x%3 == 0 || x%5 == 0)
        total = total + x;
}
  

以上解决方案是O(n),以实现更好的时间复杂度O(1)我们可以使用   Arithmetic Progression,间隔为3到5。

enter image description here

n =给定范围(1 ... R)中给定数字(Num)的倍数总数。在这种情况下(1 ... 1000)

a1 =第一个倍数。在这里是3或5。

an =最后一个倍数。即3Xn

因此,对于给定范围1 ... lastOfRange(不包括lastOfRange),以下代码将计算间隔为3/5(Num)的级数之和。

long SumOfSeries(long Num, long lastOfRange)
{
    long multiplesCount = (lastOfRange-1) / Num; //(lastOfRange-1) to exlude the last number 1000 here
    long result = multiplesCount * (Num + (multiplesCount * Num)) / 2;//Num = a1, (multiplesCount * Num) = an.
    return result;
}

,这可以称为:

long N = 1000;
Sum = SumOfSeries(3, N) + SumOfSeries(5, N) - SumOfSeries(3*5, N);
printf("%ld", total);

答案 1 :(得分:5)

可以通过简单的算术运算来计算答案,而无需进行任何迭代。许多欧拉计画的问题旨在让您思考寻找解决方案的聪明方法,而不仅仅是利用计算机的原始能力来进行计算。

给出正整数 N F ,即 F 的正整数倍数小于 N 是floor(( N -1)/ F )。 (floor( x )是不大于 x 的最大整数。)例如,小于1000的5的倍数是floor(999/5)= floor (199.8)= 199。

n 为该底数的倍数((<< em> N -1)/ F )。

第一个倍数是 F ,最后一个倍数是 n F 。例如,对于1000和5,第一个倍数是5,最后一个倍数是199•5 = 995。

倍数是均匀分布的,因此它们的平均值等于第一个和最后一个的平均值,因此为( F + n F )/ 2。

倍数的总和等于其平均值乘以它们的数量,因此 F 小于 N 的倍数的总和为 n •( F + n F )/ 2。

正如我们在其他答案和评论中所看到的,将3的倍数之和与5的倍数之和相加会计算3和5的倍数两次。我们可以通过减去这些数字的总和来对此进行更正。 3和5的倍数都是15的倍数。

因此,我们可以使用简单的算法来计算所需的总和,而无需进行任何迭代:

#include <stdio.h>


static long SumOfMultiples(long N, long F)
{
    long NumberOfMultiples = (N-1) / F;
    long FirstMultiple = F;
    long LastMultiple = NumberOfMultiples * F;

    return NumberOfMultiples * (FirstMultiple + LastMultiple) / 2;
}


int main(void)
{
    long N = 1000;
    long Sum = SumOfMultiples(N, 3) + SumOfMultiples(N, 5) - SumOfMultiples(N, 3*5);

    printf("%ld\n", Sum);
}

在处理其他Euler项目问题​​时,您应该寻找类似的想法。

答案 2 :(得分:2)

您正在做的是一些计算错误。您会看到5和3的一些常见倍数,例如15,30,45 ...,因此,由于您将这两个总和相加,因此得到了更高的价值。

稍微修改一下代码就可以解决问题。

for(x= 0; x < 1000; x += 3) 
{
   if(x%5)
   {
       a = a + x;
   }
}

for(y = 0; y < 1000; y += 5)  
     b = b + y;

z = a + b;
printf("%lu", z);

答案 3 :(得分:2)

直接翻译您的python代码:

#include <stdio.h>

int main(int argc, char *argv[])
{
  int sum = 0;

  for (int x = 0; x < 1000; x++)
  {
    if (x % 5 == 0 || x % 3 == 0)
      sum += x;
  }

  printf("%d", sum);
}

答案 4 :(得分:0)

出于乐趣,我决定给这个问题一些附加的约束。

  • 循环迭代器不能采用非整数的值
  • 数字必须按数字顺序加到总和上。

int sum_multiples(long int m1,long int m2,long int lim)
{
    long int sum=0;
    for(long int i=m1;i<lim;i=((i+m1)/m1)*m1>((i+m2)/m2)*m2?((i+m2)/m2)*m2:((i+m1)/m1)*m1) sum+=i;
    return sum;
}
int  main(int argc, char *argv[])
{
    printf("Total: %ld \n",sum_multiples(3,5,1000));
    return 0;
}

答案 5 :(得分:0)

您的带for循环的解将为O(n)。

我找到了一个更通用的解决方案O(1)。

在这里,我们可以使用另一个乘数,甚至是非素数。

#include <stdio.h>

long gcd(long a, long b) {  
    return b == 0 ? a : gcd(b, a % b);  
}

long lcm(long a, long b) {  
    return a / gcd(a, b) * b;  
}  

long sumMultiple(long mult, long to) {
    to = to / mult;
    to *= to + 1;
    return (to >> 1) * mult;
}

long calc(long a, long b, long n) {
    n--;
    return sumMultiple(a, n) + sumMultiple(b, n) - sumMultiple(lcm(a,b), n);
}

int main() {
    int n = 1000;
    printf("Sum of multiplies of 3 and 5 is %ld\n", calc(3,5,n));
    return 0;
}

答案 6 :(得分:0)

#include<stdio.h>
int main()
{
int sum;
int i;
sum=0;
for(i=0;i<1000;++i)
{
if((i%3==0)||(i%5==0))
   {
    sum=sum+i;
   }
}

printf("%d",sum);

}
  

输出为233168