Q12——Highly divisible triangular number

问题:

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秒。。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值