求出1000以下3或5的所有倍数的总和
如果我们列出10以下的所有自然数是3或5的倍数,我们得到3,5,6和9.这些倍数的总和是23.我有以下代码,但答案不匹配。
#include int main() { long unsigned int i,sum=0; clrscr(); for(i=0;i<=1000;i++) { if((i%5==0)||(i%3==0)) { sum=sum+1; } } printf("%d\n",sum); getchar(); return 0; }
两件事情:
- 你在循环中包含 1000,和
- 你每次都要加一个,而不是价值本身。
将循环更改为
for(i=0;i<1000;i++)
和总和来
sum=sum+i;
而不是使用基于范围/循环的解决方案,您可能希望利用更多的数学而不是暴力。
有一种简单的方法可以得到一个数的倍数之和,小于一个数。
例如,3到1000的倍数之和为:3 + 6 + 9 + … + 999可以改写为:3 *(1 + 2 + 3 + … + 333)
有一种简单的方法来总结所有数字1-N:
Sum(1,N) = N*(N+1)/2
所以样本函数就是
unsigned int unitSum(unsigned int n) { return (n*(n+1))/2; }
因此现在将所有3的倍数小于1000(也就是999)减少到:
3*unitSum((int)(999/3))
您可以对5的倍数执行相同的操作:
5*unitSum((int)(999/5))
但有一点需要注意! 这两个都计算了两者的倍数,例如15,30等等。它们计算两次,每次一个。 所以为了平衡这一点,你减去一次。
15*unitSum((int)(999/15))
所以总的来说,等式是:
sum = 3*unitSum((int)(999/3)) + 5*unitSum((int)(999/5)) - 15*unitSum((int)(999/15))
所以现在而不是循环遍历大量数字,并进行比较,你只是做一些简单的乘法!
也许你应该这样做
sum += i // or sum = sum + i
代替
sum = sum + 1
另外,使用printf打印long unsigned int
时要小心。 我想正确的说明符是%lu
。
它应该是sum = sum + i
而不是1
。
#include #include int main() { int x,y,n; int sum=0; printf("enter the valeus of x,y and z\n"); scanf("%d%d%d",&x,&y,&n); printf("entered valeus of x=%d,y=%d and z=%d\n",x,y,n); sum=x*((n/x)*((n/x)+1)/2)+y*((n/y)*((n/y)+1)/2)-x*y*(n/(x*y))*((n/(x*y))+1)/2; printf("sum is %d\n",sum); return 0; } // give x,y and n as 3 5 and 1000
这是一个python单行,给出了正确的答案(233168):
reduce( lambda x,y: x+y, [ x for x in range(1000) if x/3.0 == int( x/3.0 ) or x/5.0 == int( x/5.0 ) ] )
正如改进一样,您可能希望完全避免循环:
multiples of 3 below 1000 form an AP : 3k where k in [1, 333] multiples of 5 below 1000 form an AP : 5k where k in [1, 199]
如果我们避免3和5的倍数:15k,其中k在[1,66]
So the answer is : 333*(3+999)/2 + 199(5+995)/2 - 66*(15+990)/2 = 2331
68
为什么你可能想要这样做是由你去弄清楚的。
这两种方法之间时间差异的有趣事实……第二种方法只计算所需的数字,而不是迭代循环。 示例:3 *(1 + 2 + 3 + 4 … 333)(因为3 * 333 = 999和999 <1000。
static void Main(string[] args) { Stopwatch sw = new Stopwatch(); Calc calculator = new Calc(); long target = 999999999; sw.Start(); Console.WriteLine("Result: " + (calculator.calcMultipleSumFast(3,target) + calculator.calcMultipleSumFast(5, target) - calculator.calcMultipleSumFast(15, target))); sw.Stop(); Console.WriteLine("Runtime: " + sw.Elapsed); Console.WriteLine(); sw.Start(); Console.WriteLine("Result: " + (calculator.calcMultiplesSum(3, 5,1000000000))); sw.Stop(); Console.WriteLine("Runtime: " + sw.Elapsed); Console.ReadKey(); } public class Calc { public long calcMultiplesSum(long n1, long n2, long rangeMax) { long sum = 0; for (long i = 0; i < rangeMax; i++) { if ((i % n1 == 0) || (i % n2 == 0)) { sum = sum + i; } } return sum; } public long calcMultipleSumFast(long n, long rangeMax) { long p = rangeMax / n; return (n * (p * (p + 1))) / 2; } }
您可以从3
(3,6,9,12等)的步长迭代3
到1000
开始,将它们添加到sum
,
int i = 3, sum = 0; for (; i < 1000; i += 3) { sum += i; }
那么你可以从5
到1000
迭代5
(跳过3
倍数,因为它们已经被添加)将这些值加到sum
中
for (i = 5; i < 1000; i += 5) { if (i % 3 != 0) sum += i; }
然后显示sum
printf("%d\n", sum);
Python实现的问题。 短,精确,肥胖。
sum=0 for i in range(1000): if (i%3==0) or (i%5==0): sum=sum+i print sum
int Sum(int N) { long long c = 0; N--; //because you want it less than 1000 if less than or equal delete this line int n = N/3,b = N/5,u = N/15; c+= (n*(n+1))/2 * 3; c+= (b*(b+1))/2 * 5; c-= (u*(u+1))/2 * 15; return c; }
使用步进方法,您可以制作一个版本:
#include int main ( void ) { int sum = 0; for (int i = 0; i < 1000; i += 5) { sum += i; } for (int i = 0; i < 1000; i += 3) { if (i % 5) sum += i; /* already counted */ } printf("%d\n", sum); return 0; }
这样可以减少modulo
计算量。
实际上,使用计数器,您可以创建一个没有的版本:
#include int main ( void ) { int sum = 0; int cnt = 6; for (int i = 0; i < 1000; i += 5) { sum += i; } for (int i = 0; i < 1000; i += 3) { if (--cnt == 0) cnt = 5; else sum += i; } printf("%d\n", sum); return 0; }
int main(int argc, char** argv) { unsigned int count = 0; for(int i = 1; i < 1001; ++i) if(!(i % 3) && !(i % 5)) count += i; std::cout << i; return 0; }
package com.venkat.test; public class CodeChallenge { public static void main(String[] args) { int j, sum=0; for ( j = 0; j <=1000; j++) { if((j%5==0)||(j%3==0)) { sum=sum+j; } } System.out.println(sum); } }