欧拉计划第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\) 。验算无误。

posted @ 2020-02-17 15:39  quanjun  阅读(197)  评论(0编辑  收藏  举报