算法设计之Project Euler 01~10 (python3.6版与C++版实现)

一、Project Euler 01:Multiples of 3 and 5

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.

1、问题描述

如果一个数小于10,且能被3和5整除,这样的数有3,5,6,9,他们的和一共是23.

请找出小于1000,且能被3和5整除的数的和。

答案为:233168

2、第一遍刷Project Euler

思路比较简单,直接遍历1000以内的所有数,然后累加能被3和5整除的数。

python版本的代码:

def multiples(x):
    num = 0
    for i in range(x):
        if i%3==0 or i%5==0:
            num += i
    return num

print(multiples(1000))

C++版本的代码:

#include<iostream>

void multiples(int x)
{
	int num = 0;
	for (int i = 0; i < x; i++)
	{
		if ((i%3==0)||(i%5==0))
		{
			num += i;
		}
	}
	std::cout << num << std::endl;
	system("pause");
}

void main()
{
	multiples(1000);
}

 

二、Project Euler 02:Even Fibonacci numbers

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、问题描述

Fibonacci数列中的每一项都是由前两项累加得到的,前两项分别为1和2,由此可以得到Fibonacci数列的前10项。

如果一个Fibonacci数列中的所有数都不超过4000000,对这个数列中偶数值的项进行求和。

答案为:4613732

2、第一遍刷Project Euler

思路:将所有的Fibonacci数列保存,然后对其偶数值的项进行求和。

python版本代码:

# 求Fibonacci数列的函数
def Fibonacci(n):
    if (n==1):
        return 1
    elif (n==2):
        return 2
    else:
        return Fibonacci(n-1) + Fibonacci(n-2)


# 对偶数值的项求和
def main(max_num):
    # 找到小于max_num的所有Fibonacci数列
    result = [1,2]
    for i in range(3, max_num):
        result.append(Fibonacci(i))
        if Fibonacci(i) > max_num:
            result.pop(-1)
            break

    # 累加偶数值的项
    count = 0
    for value in result:
        if value%2==0:
            count += values
    print(count)
 

# 执行程序
if __name__=="__main__":
    main(4000000)

C++版本为:

#include<iostream>

int Fibonacci(int x)
{
	if (x==1)
	{
		return 1;
	}
	else if (x==2)
	{
		return 2;
	}
	else
	{
		return Fibonacci(x - 1) + Fibonacci(x - 2);
	}
}

void main()
{
	int count = 2;
	for (int i = 3; i < 4000000; i++)
	{
		if (Fibonacci(i) > 4000000)
		{
			break;
		}
		else
		{
			if (Fibonacci(i)%2==0)
			{
				count += Fibonacci(i);
			}
		}
	}
	std::cout << count << std::endl;
	system("pause");
}

 

三、Project Euler 03:Largest prime factor

Largest prime factor

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

What is the largest prime factor of the number 600851475143 ?

1、问题描述

质数指只能够被1和本身整除的数。

如果对13195分解质因数,其结果为5,7,13,29.

那么对600851475143进行分解质因数,其最大的质数为多少?

答案为:6857

2、第一遍刷Project Euler

思路:需要定义两个函数,第一个函数用于判断一个数是否为质数,以便于后续调用这个函数来找寻质因数,另一个函数用于分解一个数的质因数,然后将质因数保存到list中,并输出最后一个质数,输出结果即为我们所求的结果。下面直接给出代码:

python版本代码:

import numpy

# 判断一个数是否为质数
def is_prime(x):
    for i in range(2, int(numpy.sqrt(x))+1):        # 求平方根可以用numpy.sqrt()
        if x % i == 0:
            return False
    return True

# 找出一个数的所有质数
def find_prime(y):
    all_prime = []                                  # 定义一个list,用于存储所有质数
    for j in range(2, (int(y**0.5)+1)):             # 求平方根可以用y**0.5
        if is_prime(j):
            if y % j == 0:
                y /= j
                all_prime.append(j)                 # 将找到的质数放入list中
    print(all_prime[-1])                            # 打印最后一个质数

if __name__ == '__main__':
    find_prime(600851475143)

C++版本代码需要用到vector,代码为:

#include<iostream>
#include<vector>

bool is_prime(int x)
{
	for (int i = 2; i < ceil(sqrt(x)); i++)
	{
		if (x%i==0)
		{
			return false;
		}
	}
	return true;
}

void main()
{
        //需要注意的是这里的类型必须写成long long int
	long long int input = 600851475143;

	std::vector<int> all_prime;
	for (int i = 2; i < ceil(sqrt(input)); i++)
	{
		if (is_prime(i))
		{
			if (input%i==0)
			{
				all_prime.push_back(i);
			}
		}
	}
	std::cout << all_prime.back() << std::endl;
	system("pause");
}

 

四、Project Euler 04:Largest palindrome product

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.

1、问题描述

回文数(palindromic number)指的是不管从哪边读都是一样的数字,且能够被分解为两个数的乘积。

比如一对由两个数字组成的最大回文数(palindromic number)是9009,且9009=91×99.

那么找出一对由三个数字组成的最大回文数(palindromic number)。

答案是:906609

2、第一遍刷Project Euler

思路:回文数非常有特点,如果三个数字分别为abc,那么组成的回文数为abccba,据此可以写一个函数来生成所有的三个数字组成的回文数。同时,回文数能够分解为两个数的乘积。三个数字组成的6位数,最大可以分解为两个1000×1000以内的数,据此可以写一个分解回文数的函数。最后需要找到这个回文数,找到之后推出程序即可。

python版本的代码为:

# 生成回文数的函数
def pal_num(a, b, c):
    return a * 100001 + b * 10010 + c * 1100


# 分解回文数的函数
def can_be_divided(x):
    for i in range(999, 0, -1):
        for j in range(999, 0, -1):
            if (i*j)==x:
                print(x, " can be divided by ", i, " and ", j)
                return True
    return False


# 找最大的回文数
def main():
    for a in range(9, 0, -1):
        for b in range(9, -1, -1):
            for c in range(9, -1, -1):
                x = pal_num(a, b, c)
                if can_be_divided(x):
                    break


if __name__ == '__main__':
    main()


# 输出结果为:906609  can be divided by  993  and  913

C++版本的代码为:

#include<iostream>
#include<vector>

int pul_num(int a, int b, int c)
{
	return a * 100001 + b * 10010 + c * 1100;
}

bool can_be_divided(int x)
{
	for (int i = 999; i > 0; i--)
	{
		for (int j = 999; j > 0; j--)
		{
			if (i*j==x)
			{
				std::cout << x << " can be diveded by " << i << " and " << j << std::endl;
				return true;
			}
		}
	}
	return false;
}

void main()
{
	for (int a = 9; a > 0; a--)
	{
		for (int b = 9; b >= 0; b--)
		{
			for (int c = 9; c >= 0; c--)
			{
				int x = pul_num(a, b, c);
				if (can_be_divided(x))
				{
					goto breakloop;
				}
			}
		}
	}

	breakloop: system("pause");
}

 

五、Project Euler 05:Smallest multiple

Smallest multiple

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

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

1、问题描述

最小公倍数问题。从1到10的最小公倍数是2520。即2520能够被1,2,......,10之间的任意数整除。

那么从1到20的最小公倍数是多少?

答案为:232792560

2、第一遍刷Project Euler

思路:从1到20的最小公倍数的关键是要找出1到20的所有质数的乘积。因为质数除了1和自身,没有任何其他因数。因此,从1到20的最小公倍数,必然是20以内所有质数乘积的整数倍,因此我们可以按照这个思路来找1到20的最小公倍数。

首先我们应该先找到20以内的所有质数,然后求得这些质数的乘积。然后在这个乘积的基础上进行1到20的最小公倍数的寻找。

python版本的代码为:

import numpy


# 找到x以内的所有质数
def is_prime(x):
    for i in range(2, int(numpy.sqrt(x)) + 1):
        if x % i == 0:
            return False
    return True


# 判断这个数能否被20以内的所有合数(即非质数)整除
def all_divided(a, b, c):
    """
    函数功能:b表示所有质数的乘积,a表示这个乘积的倍数,c这里取20,表示20以内的数
    """
    num = a*b                        # 我们要进行判断的数

    for factor in range(c, 1, -1):   # 判断这个数能否被c以内的所有数整除
        if num%factor != 0:
            return False
    return True


def main(x):
    # 定义质数的乘积初始值为1
    product_prime = 1
    for i in range(1, x+1):
        if is_prime(i):
            product_prime *= i       # 求所有质数的乘积

    # 以这个乘积为标准,找寻1到20以内的最小公倍数,暂且定义循环10000次
    for j in range(1, 10000):
        if all_divided(j, product_prime, x):
            print(j*product_prime)   # 找到后打印这个数,然后结束程序
            break


if __name__ == '__main__':
    main(20)

C++版本代码为:

#include<iostream>

bool is_prime(int x)
{
	for (int i = 2; i <= sqrt(x); i++)
	{
		if (x%i == 0)
		{
			return false;
		}
	}
	return true;
}

bool all_divided(int a, int b, int c)
{
	long int num = a*b;
	for (int i = c; i > 1; i--)
	{
		if (num%i !=0)
		{
			return false;
		}
	}
	return true;
}

void main()
{	
	int x = 20;
	long int product_prime = 6;
	for (int i = 5; i < x; ++i)
	{
		if (is_prime(i))
		{
			product_prime *= i;
		}
	}

	for (int j = 1; j < 10000; j++)
	{
		if (all_divided(j, product_prime, x))
		{
			std::cout << (j)*product_prime << std::endl;
			break;
		}
	}

	system("pause");
}

 

六、Project Euler 06:Sum square difference

Sum square difference

The sum of the squares of the first ten natural numbers is,

                                                         1^{2}+2^{2}+...+10^{2} = 385 

The square of the sum of the first ten natural numbers is,

                                                         (1+2+...+10)^{2}=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.

1、问题描述

从1到10的平方的和为385,和的平方为3025,两者的差为3025 - 385 = 2640.

如果是前100个自然数,即从1到100,这两项的差值为多少? 

答案为:25164150

2、第一遍刷Project Euler

思路:记得小学时候的奥数学过,计算从1到n的平方的和,可以利用公式:

                                                               1^{2}+2^{2}+...+n^{2}=\frac{(2n+1)(n+1)n}{6}

计算从1到n的和的平方,可以利用求和公式:

                                                                   (1+2+...+n)^{2}=(\frac{n(n+1)}{2})^{2}

因此完全可以利用上述的两个公式,编写两个函数直接计算这两项的结果,然后作差即可。

下面给出代码:

python版本的代码为:

def square_sum(x):
    return (2*x+1)*(x+1)*x/6

def sum_square(x):
    return (x*(x+1)/2)**2

def main(x):
    return abs(square_sum(x)-sum_square(x))


if __name__ == '__main__':
    print(main(100))

C++版本代码为:

#include<iostream>

long long int square_sum(int n)
{
	return (2 * n + 1)*(n + 1)*n / 6;
}

long long int sum_square(int n)
{
	return (n*(n + 1) / 2) * (n*(n + 1) / 2);
}

void main()
{	
	std::cout << abs(square_sum(100) - sum_square(100)) << std::endl;
	system("pause");
}

 

七、Project Euler 07:10001st prime

10001st prime

By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.

What is the 10 001st prime number?

1、问题描述

前6个质数是2,3,5,7,11,13,第6个质数是13.

同理,那么第10001个质数是多少?

答案为:104743

2、第一遍刷Project Euler

思路:总体来说采用遍历的思路,如果一个数是质数,那么就记录下来同时计数器+1,最后当计数器=10001时输出该质数即可。这里需要写两个函数,一个是判断一个数是不是质数,另一个是遍历记录的函数。

在遍历质数的时候,除了2之后的所有质数都是奇数,因此我们可以从3开始,遍历所有的奇数,以减少循环次数。

python版本的代码为:

def is_prime(x):
    for i in range(2, int(x**0.5 + 1):          
        if x % i == 0:
            return False
    return True


def find_prime(n):
    count = 1
    prime = []

    for i in range(3, 99999999, 2):
        if count == n:
            print(count)
            return print(prime[-1])
        if is_prime(i):
            count += 1
            prime.append(i)

if __name__ == '__main__':
    find_prime(10001)

C++版本的代码为:

#include<iostream>
#include<vector>

bool is_prime(long long int x) 
{ 
	for (long long int i = 2; i <= sqrt(x); i++) 
	{ 
		if (x%i == 0) 
		{ 
			return false; 
		} 
	}	
	return true; 
}


void find_prime(long long int n)
{
	std::vector<long long int> prime;

	for (long int i = 3; i < 999999; i+=2)
	{
		if (is_prime(i))
		{
			prime.push_back(i);
		}
	}

	std::cout << prime[n-2] << std::endl;
}

void main()
{	
	find_prime(10001);
	system("pause");
}

 

八、Project Euler 08:Largest product in a series

Largest product in a series

The four adjacent digits in the 1000-digit number that have the greatest product are 9 × 9 × 8 × 9 = 5832.

                              73167176531330624919225119674426574742355349194934
                              96983520312774506326239578318016984801869478851843
                              85861560789112949495459501737958331952853208805511
                              12540698747158523863050715693290963295227443043557
                              66896648950445244523161731856403098711121722383113
                              62229893423380308135336276614282806444486645238749
                              30358907296290491560440772390713810515859307960866
                              70172427121883998797908792274921901699720888093776
                              65727333001053367881220235421809751254540594752243
                              52584907711670556013604839586446706324415722155397
                              53697817977846174064955149290862569321978468622482
                              83972241375657056057490261407972968652414535100474
                              82166370484403199890008895243450658541227588666881
                              16427171479924442928230863465674813919123162824586
                              17866458359124566529476545682848912883142607690042
                              24219022671055626321111109370544217506941658960408
                              07198403850962455444362981230987879927244284909188
                              84580156166097919133875499200524063689912560717606
                              05886116467109405077541002256983155200055935729725
                              71636269561882670428252483600823257530420752963450

Find the thirteen adjacent digits in the 1000-digit number that have the greatest product. What is the value of this product?

1、问题描述

在1000个数字中,4个相连数字的最大乘积是9*9*8*9=5832,其位置如上标红处所示。

那么请找出13个相连数字的最大乘积。

答案为:23514624000

2、第一遍刷Project Euler

思路:将1000个数字以字符串的形式读取到内存中,然后逐个遍历,并计算相邻12个数的乘积。保存最大的乘积即可。

python版本代码为:

digit_matrix = (
    "73167176531330624919225119674426574742355349194934"
    "96983520312774506326239578318016984801869478851843"
    "85861560789112949495459501737958331952853208805511"
    "12540698747158523863050715693290963295227443043557"
    "66896648950445244523161731856403098711121722383113"
    "62229893423380308135336276614282806444486645238749"
    "30358907296290491560440772390713810515859307960866"
    "70172427121883998797908792274921901699720888093776"
    "65727333001053367881220235421809751254540594752243"
    "52584907711670556013604839586446706324415722155397"
    "53697817977846174064955149290862569321978468622482"
    "83972241375657056057490261407972968652414535100474"
    "82166370484403199890008895243450658541227588666881"
    "16427171479924442928230863465674813919123162824586"
    "17866458359124566529476545682848912883142607690042"
    "24219022671055626321111109370544217506941658960408"
    "07198403850962455444362981230987879927244284909188"
    "84580156166097919133875499200524063689912560717606"
    "05886116467109405077541002256983155200055935729725"
    "71636269561882670428252483600823257530420752963450"
    )


def find_product(x):
    # 存储最大乘积的变量
    product_max = 1
    for i in range(0, 1000-x):

        # 存储相邻x数的临时变量
        product_x = 1
        for j in range(0, x+1):
            # 计算相邻x个数的乘积,ord()是将字符转换成数字,ASCII码格式,数字的编号从48起,所以减去48
            product_x *= (ord(digit_matrix[i+j])-48)

        # 记录最大的乘积
        if product_max < product_x:
            product_max = product_x

    print(product_max)

if __name__ == '__main__':
    find_product(12)        # 由于第一个数的编号是0,这里13个数则输入12

C++版本的代码为:

#include<iostream>
#include<string>

void find_product(int x, std::string number)
{
	int str_len = number.length();
	long long int product = 1;

	for (int i = 0; i < str_len - x; i++)
	{
                //计算相邻x个数的乘积
		long long int product_x = 1;
		for (int j = 0; j < x; j++)
		{
                        //数字0的ASCII码是48,因此要减去48
			product_x *= int(number[i + j] - 48);
		}
                
                //判断乘积是否是最大值    
		if (product < product_x)
		{
			product = product_x;
		}
	}

	std::cout << product << std::endl;
}

void main()
{	
	std::string number = "73167176531330624919225119674426574742355349194934"
		"96983520312774506326239578318016984801869478851843"
		"85861560789112949495459501737958331952853208805511"
		"12540698747158523863050715693290963295227443043557"
		"66896648950445244523161731856403098711121722383113"
		"62229893423380308135336276614282806444486645238749"
		"30358907296290491560440772390713810515859307960866"
		"70172427121883998797908792274921901699720888093776"
		"65727333001053367881220235421809751254540594752243"
		"52584907711670556013604839586446706324415722155397"
		"53697817977846174064955149290862569321978468622482"
		"83972241375657056057490261407972968652414535100474"
		"82166370484403199890008895243450658541227588666881"
		"16427171479924442928230863465674813919123162824586"
		"17866458359124566529476545682848912883142607690042"
		"24219022671055626321111109370544217506941658960408"
		"07198403850962455444362981230987879927244284909188"
		"84580156166097919133875499200524063689912560717606"
		"05886116467109405077541002256983155200055935729725"
		"71636269561882670428252483600823257530420752963450";
	
	find_product(13, number);
	system("pause");
}

 

九、Project Euler 09:Special Pythagorean triplet

Special Pythagorean triplet

A Pythagorean triplet is a set of three natural numbers, a < b < c, for which,

                                                                a^{2}+b^{2}=c^{2}

For example, 3^{2}+4^{2}=9+16=25=5^{2} 

There exists exactly one Pythagorean triplet for which a + b + c = 1000.
Find the product abc.

1、问题描述

一组毕达哥拉斯数是由三个数组成,且满足勾股定理,比如3,4,5

由唯一的一组毕达哥拉斯数的和为1000,求这组数的乘积

答案为:31875000

2、第一遍刷Project Euler

思路:三个数的和为1000,因此可以直接利用循环的思路来找这三个数。直接给出代码。

python版本的代码为:

def main(x):
    for i in range(1, x):
        for j in range(1, x):
            if i**2 + j**2 == (x-i-j)**2:
                print("a:{}, b:{}, c:{}, abc:{}".format(i,j,x-i-j, i*j*(x-i-j)))
                return 0

if __name__ == '__main__':
    main(1000)

C++版本的代码为:

#include<iostream>


void main()
{	
	int x = 1000;
	for (int a = 1; a < x; a++)
	{
		for (int b = 1; b < x; b++)
		{
			int c = x - a - b;

			if (a*a + b*b == c*c) 
			{
				std::cout << a*b*c << std::endl;
				goto break_loop;
			}

		}
	}
	break_loop: system("pause");
}

 

十、Project Euler 10:Summation of primes

Summation of primes

The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes below two million.

1、问题描述

小于10的所有质数的和为2+3+5+7=17

那么小于2000000的所有质数的和为多少?

答案为:142913828922

2、第一遍刷Project Euler

思路:除了2之外的所有质数都为奇数,因此可以从3开始找所有的质数。这里需要准备两个函数,一个函数用于判断一个数是否为质数,另一个函数用于存储所有的质数,并累加他们的和。

python版本的代码为:

import numpy

def is_prime(x):
    for i in range(2, int(numpy.sqrt(x))+1):        # 求平方根可以用numpy.sqrt()
        if x % i == 0:
            return False
    return True


def prime_sum(x):
    sum = 0
    prime = []

    for i in range(3, x+1, 2):
        if is_prime(i):
            prime.append(i)

    for j in prime:
        sum += j

    print(sum+2)


if __name__ == '__main__':
    prime_sum(2000000)

C++版本的代码为:

#include<iostream>
#include<vector>

bool is_prime(long long int x) 
{ 
	for (long long int i = 2; i <= sqrt(x); i++) 
	{ 
		if (x%i == 0) 
		{ 
			return false; 
		} 
	}	
	return true; 
}


void prime_sum(long long int n)
{
	long long int sum=0;
	std::vector<long long int> prime;

	for (long int i = 3; i < n; i+=2)
	{
		if (is_prime(i))
		{
			prime.push_back(i);
		}
	}

	for (auto val: prime)
	{
		sum += val;
	}

	std::cout << ((sum + 2)) << std::endl;
}

void main()
{	
	prime_sum(2000000);
	system("pause");
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全部梭哈迟早暴富

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值