问题:
The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five hundred divisors?
思路:。。。有个毛思路。。。老规矩。。一个一个死算呗。。。我又不是大牛。。。
代码:
#!/usr/bin/python
#encoding=utf-8
import math
###############主程序###################
known={0:0}
def f(n):
if n in known:
return known[n]
else:
temp=f(n-1)+n
known[n]=temp
return temp
def count (n):
co=2
start=2
while 1:
if start>int(math.sqrt(n))+1:
break
else:
if n%start==0:
co+=2
start+=1
return co
if __name__=='__main__':
startNum=0
count_divisor=0
num=0
while count_divisor<500:
startNum+=1
num=f(startNum)
count_divisor=count(num)
print num
。。啊啊。。。34秒啊。这能忍?。。看大牛的代码去。。
。。。看不懂啊。艹。。。
刚刚改进了一下:
#!/usr/bin/python
#encoding=utf-8
import math
###############主程序###################
known={0:0,1:1}
def f(n):
if n in known:
return known[n]
else:
temp=f(n-1)+n
known[n]=temp
return temp
def count (n):
mid=int(math.sqrt(n))
li=[0]*mid
li[1]=1
cot=1
start=2
while start<mid:
if li[start]==0:
if n%start==0 :
li[start]=1
cot+=1
temp=start+start
while temp<mid:
if n%temp==0 and li[temp]==0:
cot+=1
li[temp]=1
temp+=start
start+=1
if n%mid==0:
cot+=1
return cot*2
if __name__=='__main__':
startNum=3
count_divisor=0
num=0
while count_divisor<500:
startNum+=1
num=f(startNum)
count_divisor=count(num)
print num
,仍然要17秒啊。。。。别人都不到10秒,艹了。
别人的代码(2秒):
def tGen():
n = i = 1
while 1:
yield n
i, n = i+1, n+i+1
def dn2(n):
if n==1: dList={1:1}
else: dList={}
while n>1:
if n%2: limit=1
else: limit=2
for d in xrange(2,n+1,limit):
if (not(n%d)):
n=n/d
if d in dList: dList[d]+=1
else: dList.update({d:1})
break;
return reduce(lambda x,y:x*y, [x+1 for x in dList.values()])
if __name__=='__main__':
import time
s=time.time()
g=tGen()
while True:
i=g.next()
d=dn2(i)
if d>500: break
print i,d
print "time elapsed: %.3f" % (time.time()-s)
这是别人对我代码的改进:..以后要多用列表推导啊,while太慢 了。。艹了。
import math
import operator
###############主程序###################
known={0:0,1:1}
def f(n):
if n in known:
return known[n]
else:
temp=f(n-1)+n
known[n]=temp
return temp
def count(n):
mid=int(math.sqrt(n))
cot = reduce(operator.add,[1 for i in xrange(1, mid) if n % i == 0])
if n%mid==0:
cot+=1
return cot*2
if __name__=='__main__':
startNum=3
count_divisor=0
num=0
while count_divisor<500:
startNum+=1
num=f(startNum)
count_divisor=count(num)
print num
耗时3秒。。很接近了。。
这是看了那个大牛之后写,但是我不懂为什么这么算啊。
import operator
import datetime
known={1:1}
def getNum (indice):
if indice in known:
return known[indice]
else:
temp=0;
temp=getNum(indice-1)+indice
known[indice]=temp
return temp
token={2:{2:1},3:{3:1}}
def cnt(num):
if num in token:
dvalue= token[num]
else:
or_num=num
dvalue=dict()
for start in xrange(2,num+1) :
if not num%start:
dvalue[start]=1
num=num/start
break
if num==1:
token[or_num]=dvalue
return dvalue
dlist=cnt(num)
for key,value in dlist.iteritems() :
dvalue[key]=dvalue.get(key,0)+value
token[or_num]=dvalue
#print result
return dvalue
#############函数定义##############
############主程序################
if __name__=='__main__':
st=datetime.datetime.now()
start=1
cn=1
num=1
while cn<500:
start+=1
num=getNum(start)
#print num,cnt(num)
cn=reduce(operator.mul,[x+1 for x in cnt(num).values()])
print num,start
en=datetime.datetime.now()
print en-st
时间0.78秒。。