今天在一個網站上刷題,這個網站很有趣。
這個網站是純英文網站,需要註冊,登陸。
接下來,博主開啓歐拉五十講的刷題之旅啦。
Problem 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.
問題描述
如果我們列出所有低於10的自然數,它們是3或5的倍數,則得到3、5、6和9。這些倍數的總和爲23。
找出1000以下3或5的所有倍數的總和。
初級代碼
從1到999遍歷,滿足條件的數字加入輸出和中。
#include <iostream>
#include<stdio.h>
#include<stdlib.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;
return 0;
}
改進代碼
等差數列的思路,大大減少運算次數,降低時間複雜度。
求出1-999中所有3的倍數,5的倍數,15的倍數。
#include <iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main()
{
int sum,sum1,sum2,sum3;
sum1 = (3+999)*333/2;//1-999中所有被3整除的數字
sum2 = (5+995)*199/2;//1-999中所有被5整除的數字
sum3 = (15+990)*66/2;//1-999中所有被15整除的數字
sum = sum1 + sum2 - sum3;
cout<<sum;
return 0;
}
回答:233168
Problem 2:Even Fibonacci numbers
Each new term in the Fibonacci sequence is generated by adding the
previous two terms. By starting with 1 and 2, the first 10 terms will
be: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和2開始,前10個術語將是:
1,2,3,5,8,13,21,34,55,89,…
通過考慮斐波那契數列中值不超過四百萬的項,找到偶值項的總和。
初級代碼
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
int32_t Fibula[50];
int main()
{
Fibula[1] = 1;Fibula[2] = 2;
int64_t sum = Fibula[2];
for(int i=3;i<=50;i++){
Fibula[i] = Fibula[i-1] + Fibula[i-2];
if(Fibula[i] >4000000)//判斷跳出循環
break;
if(Fibula[i] % 2 == 0)
sum += Fibula[i];//求和
}
cout<<sum<<endl;
return 0;
}
回答:4613732
Problem 3:Largest prime factor
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
問題描述
13195的素因子是5、7、13和29。
什麼是600851475143的最大素因子?
代碼
任意一個合數m,都可以表示成 m=a*b的形式,而且必有a<=sqrt(m)<=b的形式。
這裏給出一種暴力求解的方法,但不具有普適性。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
#define NUM 600851475143
#define sqrtNUM 800000
int8_t mark[800001];
int main()
{
int64_t num = NUM;
int64_t max_prime;
//素數篩
memset(mark,1,sizeof(mark));
mark[0] = mark[1] = 0;
for(int c=2; c*c<sqrtNUM; c++){
if(mark[c] == 1){
for(int i=2;c*i<sqrtNUM;i++)
mark[c*i] = 0;
}
}
int32_t i;
for(i=sqrtNUM;i>1;i--){
if(mark[i] && num%i == 0)
break;
}
if(i>1)
cout<<i<<endl;
return 0;
}
改進代碼
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
#define NUM 600851475143
int main()
{
int64_t num = NUM;
int64_t max_prime;
for(int64_t i=2;i*i<=num;i++){
while(num%i==0){//進入循環的i一定是素數 因爲如果不是素數,i=a*b,a,b<i,從而a,b也可以滿足條件進入循環,顯然矛盾
num = num/i;
max_prime = i;
}
}
if(num != 1)
max_prime = num;
cout<<max_prime<<endl;
return 0;
}
回答:6857
Problem 4:Largest palindrome product
A palindromic number reads the same both ways. The largest palindrome
made from the product of two 2-digit numbers is 9009 = 91 × 99.Find the largest palindrome made from the product of two 3-digit
numbers.
問題描述
迴文數在兩個方向上都相同。由兩個兩位數的乘積構成的最大回文數爲9009 = 91×99。
查找由兩個3位數字的乘積組成的最大回文數。
初級代碼
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
//判斷一個數是否爲迴文數
bool huiwen(int n)
{
int m = n;
int b = 0;
int temp;
while(m!=0){
b = b*10;
temp = m%10;
b = b+temp;
m = m/10;
}
if(b == n)
return true;
else
return false;
}
int main()
{
int32_t max = 999*999;//max = 998001;
int32_t min = 100*100;//min = 10000;
int maxnum=0,num;
for(int i=999;i>=100;i--)
for(int j=999;j>=100;j--){
if(huiwen(i*j)){
num = i*j;
if(maxnum < num)
maxnum = num;//更新最大回文數
}
}
cout<<maxnum;
return 0;
}
回答:906609
Problem 6:Sum square difference
The sum of the squares of the first ten natural numbers is,
12+22+…+102=385
The square of the sum of the first ten natural numbers is,
(1+2+…+10)2=552=3025
Hence the difference between the sum of the squares of the first ten natural numbers and the square of the sum is
3025−385=2640
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
問題描述
前十個自然數的平方和是385
前十個自然數之和的平方爲3025
因此,前十個自然數的平方之和並將該和的平方之間的差爲3025-385=2640。
求出前一百個自然數的平方和與和的平方之差。
代碼
大家都知道高斯的1+2+3+…+100=5050
這便是1到100的自然數之和。 一般的自然數求和,我們可以用下面的公式: Sn = n * (n + 1) / 2
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
int main()
{
int32_t sum1,sum2;
sum1 = (1+100)*100/2;
sum1 = sum1*sum1;//1-100和的平方
sum2 = 100*(100+1)*(2*100+1)/6;//1-100平方的和
cout<<sum1-sum2;
return 0;
}
回答:25164150
Problem 28:Number spiral diagonals
問題描述
代碼
這裏說一下思路:
觀察這個由所有對角線元素組成的數列:
1,3,5,7,9,13,17,21,25...
其中1是最裏面一層的對角線元素,3,5,7,9是第二層的對角線元素,13,17,21,25是第三層的對角線元素。
從1到(3,5,7,9),增量add爲2
從(3,5,7,9)到(13,17,21,25),增量爲4
…
所以,我們可以把這個數列完全構造出來再求和
1,3,5,7,9,13,17,21,25,31,37,43,49,57,65,73,81,91,101,111,121...
還有一個問題要解決,10011001大小的矩陣的對角線元素一共有多少層呢?可以遞推一下。
…
第一層一共有1個數 12
第二層一共有9個數 32
第三層一共有25個數 52
…
所以第i層一共有(2i-1)2個數
由此可以知道10011001的矩陣一共有10011001個數,對應的層數爲2*i-1=1001,解得i=501
#include<iostream>
using namespace std;
int main()
{
int64_t sum =1;//最後的總和
int64_t i=1;//i表示對角線上的數
int32_t ceng = 1;//螺旋層數
//第i層需要(2*i-1)^2個數,如形成3層螺旋,需要25個數,也即是5*5
//那麼形成1001*1001,需要多少個數呢?
//2*i-1 = 1001 ,i=501,螺旋層數最大爲501,ceng<=501
int32_t add = 2;//這個數列的增量
for(ceng=2;ceng<=501;ceng++){
for(int j=1;j<=4;j++){
i += add;
sum += i;
}
add += 2;//每多一層,add+2
}
cout<<sum;
return 0;
}
改進代碼
改進一下,對每一層先求和,構造出一個數列
…
第一層對角線元素爲1, 和爲1
第二層對角線元素爲3,5,7,9,和爲24
第三層對角線元素爲13,17,21,25,和爲76
第四層對角線元素爲31,37,43,49,和爲160
…
所以第n層的對角線元素之和爲 4i2 -6i+6,其中i = 2*n-1
改進的代碼如下:
int main()
{
int64_t sum =1;//最後的總和,第一層爲1
int64_t temp=1;//i表示對角線上的數
int32_t ceng = 1;//螺旋層數
for(ceng=2;ceng<=501;ceng++){
int i = 2*ceng - 1;
temp = 4*i*i-6*i+6;
sum += temp;
}
cout<<sum;
return 0;
}
回答:669171001
Problem 30:Digit fifth powers
問題描述
代碼
這是一個估算上界的題目,每位數的5次方最大爲95約等於6*104
那麼對於某個m位數:
大致有 10m === m * 6 * 104
那麼 估計m最大也只能是6.
再粗略估計一下下限,m最小爲4
所以滿足條件的數只可能是4位數,5位數,或者6位數
#include<iostream>
using namespace std;
//求某個數n的5次冪
//注意0的n次方
//當n大於0時,等於0;
//當n等於0時,0的0次方沒有意義;
//當n小於0時,也沒有意義。
int getfifthpow(int n)
{
return n*n*n*n*n;
}
//判斷這個數是否爲滿足題目條件的特殊數字
bool issurprisenumber(int n)
{
int32_t num = 0;
int temp;
int m = n;
while(m!=0){
temp = m%10;
num += getfifthpow(temp);
m = m/10;
}
return n == num;
}
int main()
{
//只可能是4位數,5位數,或者6位數
//暴力求解
int32_t sum =0;
for(int i=1000;i<=999999;i++)
if(issurprisenumber(i)){
sum += i;
//cout<<i<<endl;
}
cout<<sum;
return 0;
}
回答:443839
Problem 34:Digit factorials
145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145.
Find the sum of all numbers which are equal to the sum of the factorial of their digits.
Note: as 1! = 1 and 2! = 2 are not sums they are not included.
問題描述
145是一個奇特的數,等於1!+ 4!+ 5!= 1 + 24 + 120 = 145。
查找所有數字的總和,這些數字等於其數字的階乘之和。
注意:爲1!= 1和2!= 2不是總和,不包括在內。
代碼
簡單枚舉算法
i從3開始循環,檢查是否符合條件的數。
粗略估算上界
9! = 362880
設最大的數有m位,則10m <= m * 9! = m * 3.6*105
所以估計m最大爲6
求解代碼
#include<iostream>
using namespace std;
//求0-9的階乘
int fact(int n)
{
int ret = 1;
if(n==0 || n==1)
return ret;
for(int i=2;i<=n;i++)
ret *= i;
return ret;
}
//判斷是否是符合條件的數
bool iscuriousnumber(int n)
{
int sum = 0;
int m = n;
while(m!=0){
sum += fact(m%10);
m = m/10;
}
return sum == n;
}
int main()
{
int32_t i=3;
int64_t ans = 0;
//i最大爲6位數
for(i=3;i<999999;i++)
if(iscuriousnumber(i)){
cout<<i<<endl;
ans += i;
}
cout<<ans;
return 0;
}
輸出這樣的數有:
145
40585
sum = 145 + 40585 = 40730
回答:40730
Problem 36:Double-base palindromes
問題描述
十進制數585 = (1001001001)(二進制表示)
因此它在這兩種進制下都是迴文數。
找出所有小於106,並且在十進制和二進制下均迴文的數,並求其的和。
(請注意,無論在何進制下,迴文數均不考慮前導零。)
代碼
上界爲106,寫一個函數來判斷一個整數n在j進制下是否爲迴文數
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
using namespace std;
#define MAXNUM 1000000
//判斷數字n在j進制下是否爲迴文數
bool ishuiwen(int n,int j)
{
int num=0;
int m = n, temp;
while(m){
num *= j;
temp = m%j;
num += temp;
m = m/j;
}
return num == n;
}
int main()
{
int ans = 0;
for(int i=1;i<MAXNUM;i++)
if(ishuiwen(i,2) && ishuiwen(i,10)){
//cout<<i<<endl;
ans += i;
}
cout<<ans;
return 0;
}
滿足條件的數十進制表示如下:
1
3
5
7
9
33
99
313
585
717
7447
9009
15351
32223
39993
53235
53835
73737
585585
ans = 872187
回答:872187