欧拉计划 Project Euler 15-21 & 67

Project Euler 15-21 & 67

Project Euler: https://projecteuler.net/
Project Euler | 欧拉计划: https://pe-cn.github.io/
Project Euler 1-7
Project Euler 8-14
Project Euler 15-21 & 67
Project Euler 22-28
Project Euler 29-35
Project Euler 36-42
Project Euler 43-49
Project Euler 50-56
Project Euler 57-63
如果有错误,还望指出,欢迎互相交流学习
随缘更新

Problem 15: Lattice paths

How many such routes are there through a 20×20 grid?

  • 排列组合问题:一共走20×2步,从中抽20步横向,20步纵向
import math
def C(n,m): # 计算组合数
    return math.factorial(n)//(math.factorial(m)*math.factorial(n-m))
C(20*2,20)
137846528820

Problem 16: Power digit sum

What is the sum of the digits of the number 2 1000 2^{1000} 21000?

  • 用数组模拟10进制进位
NUM = [1]
carry = 0
for i in range(1000):
    carry = 0
    for j in range(len(NUM)):
        temp = NUM[j] * 2 + carry
        if temp>9:
            NUM[j] = temp%10
            carry = temp//10
        else:
            carry = 0
            NUM[j] = temp
    if carry!=0:
        NUM.append(carry)
print(sum(NUM))
1366

Problem 17: Number letter counts

If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?

def	LetterCounts(num):
    if(num == 1):     return 3   #one
    if(num == 2):     return 3   #two
    if(num == 3):     return 5   #three
    if(num == 4):     return 4   #four
    if(num == 5):     return 4   #five
    if(num == 6):     return 3   #six
    if(num == 7):     return 5   #seven
    if(num == 8):     return 5   #eight
    if(num == 9):     return 4   #nine
    if(num == 10):    return 3   #ten
    if(num == 11):    return 6   #eleven
    if(num == 12):     return 6   #twelve
    if(num == 13):     return 8   #thirteen
    if(num == 14):     return 8   #fourteen
    if(num == 15):     return 7   #fifteen
    if(num == 16):     return 7   #sixteen
    if(num == 17):     return 9   #seventeen
    if(num == 18):     return 8   #eighteen
    if(num == 19):     return 8   #nineteen
    if(num == 20):     return 6   #twenty
    if(num == 30):     return 6   #thirty
    if(num == 40):     return 5   #forty
    if(num == 50):     return 5   #fifty
    if(num == 60):     return 5   #sixty
    if(num == 70):     return 7   #seventy
    if(num == 80):     return 6   #eighty
    if(num == 90):     return 6   #ninety
    return 0
# 解一:计算1-1000每个数的长度
def Number_letter_counts(num):
    Sum = 0
    if num//1000:
        Sum += LetterCounts(num//1000) + len('thousand')
        num = num%1000
    if num//100:
        Sum += LetterCounts(num//100) + len('hundred')
        num = num%100
        if num:
            Sum += len('and')
    if num>20:
        Sum += LetterCounts((num//10)*10) + LetterCounts(num%10)
    else:
        Sum += LetterCounts(num)
    return Sum
Sum = 0
for i in range(1,1001):
    Sum += Number_letter_counts(i)
print(Sum)
21124
# 解二:避免了重复计算
Sum = 0
for i in range(1,100):
    Sum += Number_letter_counts(i)
Sum =10*Sum
for i in range(1,10):
    Sum += 99*(LetterCounts(i) + len('hundredand'))
for i in range(1,10):
    Sum += (LetterCounts(i) + len('hundred'))
print(Sum+len('onethousand'))
21124

Problem 18: Maximum path sum I

Find the maximum total from top to bottom of the triangle below :L

  • 从上到下,计算小三角从头到最后一行每个元素路径的最大和,逐步更新每行
L = [
    [75],
    [95,64],
    [17,47,82],
    [18,35,87,10],
    [20, 4,82,47,65],
    [19, 1,23,75, 3,34],
    [88, 2,77,73, 7,63,67],
    [99,65, 4,28, 6,16,70,92],
    [41,41,26,56,83,40,80,70,33],
    [41,48,72,33,47,32,37,16,94,29],
    [53,71,44,65,25,43,91,52,97,51,14],
    [70,11,33,28,77,73,17,78,39,68,17,57],
    [91,71,52,38,17,14,91,43,58,50,27,29,48],
    [63,66, 4,68,89,53,67,30,73,16,69,87,40,31],
    [ 4,62,98,27,23, 9,70,98,73,93,38,53,60, 4,23],
]
for i in range(1,len(L)):
    L[i][0] = L[i-1][0] + L[i][0]
    L[i][-1] = L[i-1][-1] + L[i][-1]
    for j in range(1,len(L[i])-1):
        L[i][j] = max(L[i-1][j-1] + L[i][j],L[i-1][j] + L[i][j])
print(max(L[len(L)-1]))
1074

Problem 67: Maximum path sum II

Find the maximum total from top to bottom of the triangle below :p067_triangle.txt

f = open('data/p067_triangle.txt')
triangle = f.readlines()
f.close()
L = []
for i in range(len(triangle)):
    L.append(triangle[i].split(' ')) 
    for j in range(len(L[i])):
        L[i][j] = int(L[i][j])
# 读取数据
for i in range(1,len(L)):
    L[i][0] = L[i-1][0] + L[i][0]
    L[i][-1] = L[i-1][-1] + L[i][-1]
    for j in range(1,len(L[i])-1):
        L[i][j] = max(L[i-1][j-1] + L[i][j],L[i-1][j] + L[i][j])
print(max(L[len(L)-1]))
7273

Problem 19: Counting Sundays

How many Sundays fell on the first of the month during the twentieth century (1 Jan 1901 to 31 Dec 2000)?

days = 0
ans = 0
for i in range(101):
    for j in range(1,13):
        if j in (4,6,9,11):
            days += 30
        elif j == 2:
            days += 28
            if ((1900+i)%4 == 0) and i>0:
                days += 1
        else:
            days += 31
        if ((days+2)%7==1) and i>0:
            ans = ans+1
print(ans)
171

Problem 20: Factorial digit sum

Find the sum of the digits in the number 100 ! 100! 100!

  • 用数组模拟大数
NUM = [1]
carry = 0
for i in range(1,101):
    carry = 0
    for j in range(len(NUM)):
        temp = NUM[j] * i + carry
        if temp>9:
            NUM[j] = temp%10
            carry = temp//10
        else:
            carry = 0
            NUM[j] = temp
    if carry!=0:
        while(carry):
            NUM.append(carry%10)
            carry //= 10 
print(sum(NUM))
648

Problem 21: Amicable numbers

Evaluate the sum of all the amicable numbers under 10000.

import math
def proper_divisors(n):
    L = []
    for i in range(1,n//2+1):
        if n % i == 0:
            L.append(i)
    if n==1:
        return []
    return L
proper_divisors(284)
[1, 2, 4, 71, 142]
L = []
Sum = 0
for i in range(10001):
    L.append(0)
for i in range(1,10001):
    temp = sum(proper_divisors(i))
    if temp<10000:
        if L[temp]==i:
            Sum += (temp + i)
    L[i] = temp
print(Sum)
31626
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值