欧拉计划第1题题解
Multiples of 3 and 5
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
3的倍数和5的倍数
如果我们列出10以内所有3或5的倍数,我们将得到3、5、6和9,这些数的和是23。
求1000以内所有3或5的倍数的和。
解题思路
区间 \([1,n]\) 范围内 \(a\) 的倍数构成了一个首项为 \(a\) ,末项为 \(\lfloor \frac{n}{a} \rfloor \cdot a\),项数为 \(\lfloor \frac{n}{a} \rfloor\) 的等差数列。
所以我们可以通过等差数列求和公式((首项+末项) \(\times\) 项数 /2)直接获得求这个等差数列的和为:
\[\frac{(a + \lfloor \frac{n}{a} \cdot a \rfloor) \times \lfloor \frac{n}{a} \rfloor}{2}
\]
我们定义函数 \(f(n,a)\) 表示区间 \([1, n]\) 范围内所有 \(a\) 的倍数之和,则本题的答案即为:
\[f(100,3) + f(100,5) - f(100, 15)
\]
因为计算 \(3\) 的倍数 和 \(5\) 的倍数的同时,我们重复计算了一个 \(15\) 的倍数,所以需要将这部分重的内容减掉。
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
int f(int n, int a) {
return (a + n/a*a) * (n/a) / 2;
}
int main() {
cout << f(100, 3) + f(100, 5) - f(100, 15) << endl;
return 0;
}
得到答案为 \(2418\)。
然后我这里再用暴力解法测试一下答案有没有问题。暴力解法就是枚举区间 \([1,100]\) 范围内每一个数,然后如果他是3或5的倍数,就把它加到总和里面去,最后输出总和。
暴力代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
int sum = 0;
for (int i = 1; i <= 100; i ++)
if (i % 3 == 0 || i % 5 == 0)
sum += i;
cout << sum << endl;
return 0;
}
可以发现,答案仍然是 \(2418\) 。验算无误。