ProjectEuler,1-10题

来源:互联网 发布:c4d下载mac 破解 编辑:程序博客网 时间:2024/06/03 22:39

先介绍一下,ProjectEuler,欧拉工程,是一个国外的练习数论的网站,总共300多道题目。

网址是http://projecteuler.net/problems,有个特点是可以使用任何编程语言,或者自己手算,得到答案提交就可以了。

这个和OJ是不一样的。提交通过以后,可以去论坛看看那别人的解决方法,以及参与讨论。


好久没有动手做题了,那天看到论坛又有人在说,就来做做。我使用的语言是python,Life is short,you need Python


前面的题目很基础,但是刷水体不是我的风格,所以我尽量用高效的,不一样的的方法来解决。


1
Add all the natural numbers below one thousand that are multiples of 3 or 5.

没什么特别的,用容斥就可以了

def main():MAX = 999print 3 * (MAX/3)*(MAX/3+1) /2 + 5 * (MAX/5)*(MAX/5+1) /2  - 15 * (MAX/15)*(MAX/15+1) /2 if __name__ == '__main__':main()


2
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

这一题是寻找一个小于4000000的最大的那个fibonacci数,

答案很小,朴素方法几行就写完了,但是我还是选择用高级方法

我们可以用矩阵快速幂乘来以O(logN)的时间获得第N个fibonacci数,然后我们选定范围二分答案就可以了

#|Fn+1| = |1 1| * |Fn  |#|Fn  |   |1 0|   |Fn-1|##|Fn+1| = (|1 1|)**n * |F1|#|Fn  |   (|1 0|)      |F0|class matrix:def __init__(self,data):self.data = datadef multiple(self, m2):N = len(self.data)if isinstance(m2,matrix):m2 = m2.datanew = []for i in range(N):new.append([0]*N)for i in range(N):for j in range(N):for k in range(N):new[i][j] += self.data[i][k]*m2[k][j]return matrix(new)def __str__(self):return str(self.data)def __repr__(self):return str(self.data)class Fibonacci():def __init__(self,N):fac = matrix([[1,1],[1,0]])self.base = []for i in range (N-1):self.base.append(fac)fac = fac.multiple(fac)def get(self,N):i = 0a = matrix([[1,0],[0,1]])while N > 0:if N&1 > 0:a = a.multiple(self.base[i])N >>= 1i+=1return a.data[1][0]+a.data[1][1]def bs_ans(low, high,limit):f = Fibonacci(10)ans = 0ans_p = 0while low <= high:v = f.get((low+high)>>1)if v > limit:high = (low+high)/2-1else:ans = vans_p = (low+high)/2low = (low+high)/2 + 1return ans_p,ansdef main():p,limit =  bs_ans(1,50,4000000)while True:if (p + 1) % 3 == 0:breakp -= 1f = Fibonacci(10)print (f.get(p+2)-1)/2if __name__ == '__main__':main()



3
Find the largest prime factor of a composite number.

寻找一个数的最大的质因子,直接分解质因数就可以了。数量比较小,用的最基础的分解质因数的方法,有兴趣的同学可以看看

import mathdef PrimeList(N = None,limit = None):if N ==None and limit ==None:raise Exception('need either N or limit')ans = [2,3]i = 5dt = 2while True:if N != None and len(ans) >= N : breakif limit != None and ans[-1] >= limit: break f = Truefor j in ans:if i%j == 0:f = Falsebreakif f:ans.append(i)i += dtdt = 6 - dtreturn ansdef IntegerFactorization(N):passdef main():N = 600851475143a = math.sqrt(N)print aplist = PrimeList(limit=a)[::-1]for p in plist:if N % p == 0:print pbreakif __name__ == '__main__':main()



4
Find the largest palindrome made from the product of two 3-digit numbers.

没想到什么好方法,暴力的

def main():ans = 0for i in xrange(100,1000):for j in xrange(100,1000):v = i * jd = str(v)e=d[::-1]if d == e:if v > ans:ans = vprint ansif __name__ == '__main__':main()



5
What is the smallest number divisible by each of the numbers 1 to 20?

典型的最小公倍数,N个数的最小公倍数,等于LCM(A1,LCM(A2,A3,...An-1))

def GCD(L):if len(L) > 2:return GCD([L[0], GCD(L[1:])])a = max(L)b = min(L)while a % b != 0:t = bb = a % ba = treturn bdef LCM(L):if len(L) > 2:return LCM([L[0],LCM(L[1:])])return L[0] * L[1] / GCD(L)print GCD(range(1,21))print LCM(range(1,21))


6
What is the difference between the sum of the squares and the square of the sums?

好吧大整数的题目(python完全没有感觉...),暴力的

print sum(range(101))**2 - sum([x**2 for x in range(101)])


7
Find the 10001st prime.

找第几个质数,因为数量稍大了,所以用了填充法筛质数,比较常用的方法

def PrimeList(N = None,limit = None):if N ==None and limit ==None:raise Exception('need either N or limit')ans = [2,3]i = 5dt = 2while True:if N != None and len(ans) >= N : breakif limit != None and ans[-1] >= limit: break f = Truefor j in ans:if i%j == 0:f = Falsebreakif f:ans.append(i)i += dtdt = 6 - dtreturn ansdef IntegerFactorization(N):passprint PrimeList(10001)[-1]


8
Discover the largest product of five consecutive digits in the 1000-digit number.

这题可以注意到如果序列中有0,就全为0了。所以我们可以用0,分割序列,然后每个序列如果长度少于5 就可以直接skip

剩下的每个子序列单独暴力就ok了。

def calc(L,N):m = 0for i in xrange(len(L)-N+1):ans = reduce(lambda m,n:m*n,L[i:i+N])if ans >m:m = ansreturn mdef main():s = '''7316717653133062491922511967442657474235534919493496983520312774506326239578318016984801869478851843858615607891129494954595017379583319528532088055111254069874715852386305071569329096329522744304355766896648950445244523161731856403098711121722383113622298934233803081353362766142828064444866452387493035890729629049156044077239071381051585930796086670172427121883998797908792274921901699720888093776657273330010533678812202354218097512545405947522435258490771167055601360483958644670632441572215539753697817977846174064955149290862569321978468622482839722413756570560574902614079729686524145351004748216637048440319989000889524345065854122758866688116427171479924442928230863465674813919123162824586178664583591245665294765456828489128831426076900422421902267105562632111110937054421750694165896040807198403850962455444362981230987879927244284909188845801561660979191338754992005240636899125607176060588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450'''s = [map(int,list(s)) for s in [subs for subs in ''.join(s.split()).split('0') if len(subs) > 4]]ans = 0for l in s:r = calc(l,5)if r > ans:ans = rprint ansif __name__ == '__main__':main()


9
Find the only Pythagorean triplet, {abc}, for which a + b + c = 1000.

算了半天,还是暴力的

def main():for a in xrange(1,1001):b = awhile a*a + b*b <= (1000-a-b)**2:if a*a + b*b == (1000-a-b)**2:print a,b,1000-a-bprint a*b*(1000-a-b)b += 1if __name__ == '__main__':main()


10
Calculate the sum of all the primes below two million.又是质数打表,直接copy代码ok

import mathdef PrimeList(N = None,limit = None):'''return first N primes or  primes <= limit'''if N ==None and limit ==None:raise Exception('need either N or limit')ans = [2,3]i = 5dt = 2while True:if N != None and len(ans) >= N : breakif limit != None and ans[-1] >= limit: break f = Truefor j in ans:if i%j == 0:f = Falsebreakif f:ans.append(i)i += dtdt = 6 - dtreturn ansdef PrimeListFill(limit):'''return primes <= limit'''A = [True] * (limit + 1)plist = PrimeList(limit=int(math.sqrt(limit)))for p in plist:n = 2 * pwhile n <= limit:A[n] = Falsen += pans = []for i in xrange(2,len(A)):if A[i]:ans.append(i)return ansdef main():L = PrimeListFill(2000000)print sum(L)if __name__ == '__main__':main()


原创粉丝点击