Project Euler 80笔记

  • 题目:
    It is well known that if the square root of a natural number is not an integer, then it is irrational. The decimal expansion of such square roots is infinite without any repeating pattern at all.
    The square root of two is 1.41421356237309504880..., and the digital sum of the first one hundred decimal digits is 475.
    For the first one hundred natural numbers, find the total of the digital sums of the first one hundred decimal digits for all the irrational square roots.
  • 题目大意:
    对于前100个自然数,找到所有无理平方根的前100个十进制数字的数字和的总和。
  • 题目分析:
    显然本题的难点在如何精确的求出无理平方根的前100个十进制数字,如果我们可以找到一种算法,能精确的求出该问题的答案,那么本题就得以解决。
    普通的牛顿法等方法由于存在小数,故精度不好控制,且收敛速度较慢。在google的时候,无意间找到一种不需要使用小数的求根方法,故尝试用此法解决问题
    介绍算法的论文链接
  • 算法伪代码:
初始化步骤:
置a = 5n, b = 5(n为要求平方根的数)
循环步骤:
  若 a >= b 则 :令a = a - b; b = b + 10
  若 a < b  则: 在a的末尾添加两个0,在b的倒数第二位添加一个0
结果:
  随着计算的进行, b会越来越接近n的平方根的十进制数串。
  • python代码:
def digitsum100(n):
    s = str(n)
    print(s)
    ans = 0
    for i in range(100):
        ans += int(s[i])
    return ans

def longsqrt(n):
    a, b = 5*n, 5
    while len(str(b)) < 103:
        if a >= b:
            ta, tb = a, b
            a = a - b
            b = b + 10
        else:
            ta, tb = a, b
            a = a * 100
            sa = a
            t = b % 10
            b = (b - t) * 10 + t
            sb = b
    return b

def check(n):
    if int(n**0.5)**2 != n:
        return True
    return False

def solve():
    ans = 0
    for i in range(1, 101):
        if check(i):
            tmp = longsqrt(i)
            print(i, tmp)
            ans += digitsum100(tmp)
    return ans

print(solve())

运行结果:

40886

你可能感兴趣的:(Project Euler 80笔记)