罗马不是一天建成的,你也不会一下成为梦想中的人,但是只要在学习在努力,就是越来越接近的。
继续上一次的Project Euler的题解,不见得最优,也不见得优雅,但是答案是对的,思路也是没问题的。这次是31~40题。
(奇怪,这人怎么又开始用python写了
Problem 31: Coin sums
嗯。。挺经典挺常见的完全背包DP问题,但是我满脑子不知道在想什么,愣是没做出来,后来看了看别人的提示才想到应该按照硬币种类去循环。一直在想怎么去处理重复的情况。
这里是这道题的详细解释
这里是完全背包、01背包、多重背包的比较的参考资料(我没看
def pro31():
# 完全背包DP
coin = [1, 2, 5, 10, 20, 50, 100, 200]
methods = [0]*300
methods[0] = 1
for k in coin:
for i in range(1, 210):
if i >= k:
methods[i] += methods[i-k]
print(methods[200])
Problem 32: Pandigital products
很蠢的一个做法,每一个去遍历判断的
def pro32():
out = []
for i in range(10, 10000):
numl = []
k = i
while k != 0:
if k % 10 not in numl:
numl.append(k % 10)
k = k//10
else:
break
if k == 0:
for j in range(2, int(math.sqrt(i))):
if i % j == 0:
numll = []
k = j
while k != 0:
if (k % 10 not in numl) and (k % 10 not in numll):
numll.append(k % 10)
k = k//10
else:
break
if k == 0:
k = i//j
while k != 0:
if (k % 10 not in numl) and (k % 10 not in numll):
numll.append(k % 10)
k = k//10
else:
break
if (k == 0) and (len(numl)+len(numll) == 9) and (0 not in numl) and (0 not in numll):
print("%d %d %d" % (i, j, i//j))
if i not in out:
out += [i]
print(sum(out))
Problem 33: Digit cancelling fractions
这个问题第一次考虑的时候考虑错了,以为分子和分母相同的数字肯定一个在十位一个在个位的,导致一开始答案是错误的。其实可以在外层循环增加一些判断,这样速度会快一些。。。
def pro33():
for i in range(10, 98):
for k in range(i+1, 99):
for j in str(i):
if j in str(k):
if i % 10 == int(j) and (k % 10) != 0:
if ((i//10) / (int(str(k).replace(j, '', 1)))) == i/k:
print("%d %d" % (i, k))
elif k % 10 != 0:
if ((i % 10) / (int(str(k).replace(j, '', 1)))) == i/k:
print("%d %d" % (i, k))
Problem 34: Digit factorials
算就对了
def pro34():
out = 0
for i in range(3, 100000):
k = i
sum = 0
while k != 0:
sum += math.factorial(k % 10)
k = k//10
if sum == i:
print(i)
out += i
print(out)
Problem 35: Circular primes
遍历,判断质数的程序又写了python版的,在最后贴上来
def pro35():
out = 4
for i in range(11, 1000000, 2):
if isPrime(i):
if i == 11:
i = 11
num = 0
for k in range(1, len(str(i))):
j = int(str(i)[k:]+str(i)[:k])
if not isPrime(j):
num += 1
break
if num == 0:
print(i)
out += 1
print(out)
Problem 36: Double-base palindromes
遍历,不讲(不过python确实行数少很多
def pro36():
out = 0
for i in range(1, 1000000):
k = str(i)
if k == k[::-1]:
k = bin(i)[2:]
if k == k[::-1]:
print(i)
out += i
print(out)
Problem 37: Truncatable primes
遍历。。。
def pro37():
out = 0
for i in range(11, 1000000, 2):
if isPrime(i):
n = 0
for k in range(1, len(str(i))):
if not isPrime(int(str(i)[k:])):
n += 1
break
if not isPrime(int(str(i)[:k])):
n += 1
break
if n == 0:
print(i)
out += i
print(out)
Problem 38: Pandigital multiples
同上。。。(这次题没有好玩的呀
def pro38():
for i in range(5, 10000):
nums = []
leng = 0
k = i
while k != 0:
if k % 10 not in nums:
nums.append(k % 10)
k = k//10
if len(nums) != len(str(i)):
continue
leng += len(nums)
for j in range(2, 10):
k = j*i
while k != 0:
if k % 10 not in nums:
nums.append(k % 10)
k = k//10
if len(nums)-leng != len(str(j*i)):
break
leng = len(nums)
if (leng == 9) and (0 not in nums):
print(i)
Problem 39: Integer right triangles
遍历。。,这个题判断条件可以仔细思考一下,能节约很多无效的计算
def pro39():
# solution计算有问题,有重复情况,但是题目不要求~~~
solution = 0
out = 0
for p in range(10, 1000):
so = 0
for a in range(p//3, p-2):
for b in range(1, a-1):
c = p-a-b
if c > 0 and a*a == b*b+c*c:
so += 1
if so > solution:
solution = so
out = p
print(out)
Problem 40: Champernowne’s constant
蠢遍历
def pro40():
# 蠢办法 is coming
out = 1
count = 1
nums = [1, 10, 100, 1000, 10000, 100000, 1000000]
for i in range(1, 100000):
k = str(i)
while len(k) != 0:
if count in nums:
out = out*int(k[0])
print(k[0])
count += 1
k = k[1:]
print(out)
Prime (python)
def isPrime(n):
if not hasattr(isPrime, 'prime'):
isPrime.prime = [2, 3, 5, 7]
if n < isPrime.prime[-1]:
return n in isPrime.prime
else:
i = isPrime.prime[-1]+2
while n > isPrime.prime[-1]:
num = 0
for k in isPrime.prime:
if i % k == 0:
num += 1
break
if k > math.sqrt(i):
break
if num == 0:
isPrime.prime.append(i)
i += 2
return n in isPrime.prime
def isPrimeS(n):
if n < 2:
return False
if n % 2 == 0:
return False
if n % 3 == 0:
return False
for k in range(2, int(math.sqrt(n))):
if n % k == 0:
return False
return True