祝各位读者新年快乐!
新年新气象,开了一个新坑,欧拉计划简介。
本系列希望以通俗易懂的语言、简洁的代码,带大家体会数学与编程结合的魅力。
标签:倍数、容斥原理、等差数列
原文: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 3、5、15 在小于 1000 1000 1000 的各自的倍数之和分别为 166833 、 99500 、 33165 166833、99500、33165 166833、99500、33165。
通过容斥原理可知, 15 15 15 的倍数在 3 、 5 3、5 3、5 的倍数里面被算了两次,所以要减掉一份。
代码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
标签:斐波那契数列
原文: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;
}
标签:质因数分解
原文: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) O(n?)
算法流程:扫描 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) O(n?)。
代码:
#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;
}
标签:枚举、回文数
原文: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;
}
标签:最大公约数、最小公倍数
原文: 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.”
“欧拉计划的存在,是为了每个对数学感兴趣的人,鼓励他们,挑战他们,并最终培养他们的能力与乐趣。”