欧拉计划 1-5题解

发布时间:2024年01月02日

祝各位读者新年快乐!

新年新气象,开了一个新坑,欧拉计划简介

本系列希望以通俗易懂的语言、简洁的代码,带大家体会数学与编程结合的魅力。

Problem 1:Multiples of 3 3 3 or 5 5 5

标签:倍数、容斥原理、等差数列

原文:If we list all the natural numbers below 10 10 10 that are multiples of 3 3 3 or 5 5 5, we get 3 3 3, 5 5 5, 6 6 6 and 9 9 9. The sum of these multiples is 23 23 23.

Find the sum of all the multiples of 3 3 3 or 5 5 5 below 1000 1000 1000.

翻译:在小于 10 10 10 的自然数中, 3 3 3 5 5 5 的倍数有 3 3 3 5 5 5 6 6 6 9 9 9,这些数之和是 23 23 23

求小于 1000 1000 1000 的自然数中所有 3 3 3 5 5 5 的倍数之和。

题解1:循环枚举一下。

代码1

#include <bits/stdc++.h>
using namespace std;

int main() {
    int sum = 0;
    for (int i = 1; i < 1000; i++) {
        if (i % 3 == 0 || i % 5 == 0) {
            sum += i;
        }
    }
    cout << sum << endl;
    return 0;
}

题解2:小于 1000 1000 1000 3 3 3 的倍数有 999 / 3 = 333 999/3=333 999/3=333 个,小于 1000 1000 1000 5 5 5 的倍数有 999 / 5 = 199 999/5=199 999/5=199 个,同时是 3 3 3 5 5 5 的倍数有 1000 / 15 = 66 1000/15=66 1000/15=66 个。

通过等差数列求和公式,我们可以求得 3 、 5 、 15 3、5、15 3515 在小于 1000 1000 1000 的各自的倍数之和分别为 166833 、 99500 、 33165 166833、99500、33165 1668339950033165

通过容斥原理可知, 15 15 15 的倍数在 3 、 5 3、5 35 的倍数里面被算了两次,所以要减掉一份。

代码2

#include <bits/stdc++.h>
using namespace std;

int main() {
    int n3 = 999 / 3;
    int n5 = 999 / 5;
    int n15 = 999 / 15;

    int S3 = (1 + n3) * 3 * n3 / 2;
    int S5 = (1 + n5) * 5 * n5 / 2;
    int S15 = (1 + n15) * 15 * n15 / 2;
    cout << S3 + S5 - S15;
    return 0;
}
// 等差数列求和:Sn = (1 + n) * d * n / 2

Problem 2:Even Fibonacci numbers

标签:斐波那契数列

原文:Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 1 1 and 2 2 2, the first 10 10 10 terms will be:

1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , … 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, \ldots 1,2,3,5,8,13,21,34,55,89,

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

翻译:斐波那契数列中的每一项都是前两项的和。由 1 1 1 2 2 2 开始生成的斐波那契数列的前 10 10 10 项为:

1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 , 55 , 89 , … 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, \ldots 1,2,3,5,8,13,21,34,55,89,

考虑该斐波那契数列中不超过四百万的项,求其中为偶数的项之和。

题解:简单打表 可以得到第 33 33 33 个斐波那契数列就超过四百万了,求解一下斐波那契数列,把前 32 32 32 项中偶数值的相加一下求和。

代码

#include <bits/stdc++.h>
using namespace std;

int f[50];

int main() {
    int sum = 0;
    f[0] = f[1] = 1;
    for (int i = 1; i <= 40; i++) {
        f[i] = f[i - 1] + f[i - 2];
        if (f[i] > 4000000) break;
        if (f[i] % 2 == 0) sum += f[i];
    }
    cout << sum << endl;
    return 0;
}

Problem 3:Largest prime factor

标签:质因数分解

原文:The prime factors of 13195 13195 13195 are 5 5 5, 7 7 7, 13 13 13 and 29 29 29.

What is the largest prime factor of the number 600851475143 600851475143 600851475143?

翻译 13195 13195 13195 的质因数包括 5 5 5 7 7 7 13 13 13 29 29 29

600851475143 600851475143 600851475143 的最大质因数是多少?

题解:直接质因数分解进行求解即可,时间复杂度为 O ( n ) O(\sqrt n) On ?

算法流程:扫描 2 ? n 2?\sqrt n 2?n ? 的每个数 x x x,若 x x x 能整除 n n n,则从 n n n 中除掉所有质因子 x x x

上述算法 保证一个合数的因子一定在扫描到这个合数之前除掉了,所以这个过程中所得到的能整除 n n n 的一定是质数。时间复杂度为 O ( n ) O(\sqrt n) On ?

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main() {
    ll n = 600851475143, mx = 0;
    for (ll i = 2; i <= sqrt(n); i++) {
        while (n % i == 0) {
            n /= i;
            mx = max(mx, i);
        }
    }
    if (n > 1) mx = max(mx, n);
    cout << n << endl;
    return 0;
}

Problem 4:Largest palindrome product

标签:枚举、回文数

原文:A palindromic number reads the same both ways. The largest palindrome made from the product of two 2 2 2-digit numbers is 9009 = 91 × 99 9009 = 91 \times 99 9009=91×99.

Find the largest palindrome made from the product of two 3 3 3-digit numbers.

翻译:回文数是指从前往后读和从后往前读都一样的数。由两个 2 2 2 位数相乘得到的回文数中,最大的是 9009 = 91 × 99 9009 = 91 \times 99 9009=91×99

求最大的由两个 3 3 3 位数相乘得到的回文数。

题解:直接枚举两个在 100 100 100 ~ 999 999 999 之间的数,对它们的乘积做一个回文数判定,数据范围比较小,可以直接数字翻转一下判断。

代码

#include <bits/stdc++.h>
using namespace std;

bool check(int a) {
    int b = a, c = 0;
    while (b > 0) {
        c = 10 * c + b % 10;
        b /= 10;
    }
    return c == a;
}

int main() {
    int mx = 0;
    for (int i = 100; i <= 999; i++)
    for (int j = 100; j <= 999; j++) {
        if (check(i * j)) mx = max(mx, i * j);
    }
    cout << mx << endl;
    return 0;
}

Problem 5:Smallest multiple

标签:最大公约数、最小公倍数

原文 2520 2520 2520 is the smallest number that can be divided by each of the numbers from 1 1 1 to 10 10 10 without any remainder.

What is the smallest positive number that is evenly divisible by all of the numbers from 1 1 1 to 20 20 20

翻译 2520 2520 2520 是最小的能够被 1 1 1 10 10 10 整除的正数。

最小的能够被 1 1 1 20 20 20 整除的正数是多少?

题解:很显然是求最小公倍数。

最大公约数( g r e a t e s t ? c o m m o n ? d i v i s o r greatest\ common \ divisor greatest?common?divisor): g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)

最小公倍数( l e a s t ? c o m m o n ? m u l t i p l e least \ common \ multiple least?common?multiple): l c m ( a , b ) = a ? b / g c d ( a , b ) lcm(a,b)=a*b/gcd(a,b) lcm(a,b)=a?b/gcd(a,b)

代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
ll gcd(ll a, ll b) {
    if (b == 0) return a;
    return gcd(b, a % b);
}

int main() {
    ll k = 1;
    for (ll i = 1; i <= 20; i++) {
        k = k * i / gcd(k, i);
    }
    cout << k << endl;
    return 0;
}

“Project Euler exists to encourage, challenge, and develop the skills and enjoyment of anyone with an interest in the fascinating world of mathematics.”

“欧拉计划的存在,是为了每个对数学感兴趣的人,鼓励他们,挑战他们,并最终培养他们的能力与乐趣。”

文章来源:https://blog.csdn.net/oitutor/article/details/135330702
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。