No_23Non-abundant sums

来源:互联网 发布:西部数码域名转移管理 编辑:程序博客网 时间:2024/05/01 23:52
问题描述:

A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.

A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.

As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.

Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

思路:

先创建一个数组,下标表示该数。值表示该数据是不是abundant。

建立一个abundant的列表listA。
遍历(1,28123)

每当求出一个abundant数字A。则A与listA中的每个数字之后肯定就可以去掉了。


代码描述:

#coding=utf-8import math,datetimedef factor(num):    relist=[1]    for temp in xrange(2,int(math.sqrt(num)+2)):        if not num%temp:            relist.extend([temp,num/temp])    return relistdef isabundant(num):    factorlist=factor(num)    if reduce(lambda x,y:x+y,factorlist)>num:        return True    else:        return Falsestart_time=datetime.datetime.now()maxint=28133t_list=[0]*(maxint+1)#要遍历的数据abundantlist=[]for tempint in xrange(1,maxint+1):    if t_list[tempint]==1:        continue    if isabundant(tempint):         t_list[tempint]=1         for value in  abundantlist:             if tempint+value<=maxint:                 t_list[tempint+value]=1         abundantlist.append(tempint)count=0for key,item in enumerate(t_list):    if item==0:        count+=keyprint countend_time=datetime.datetime.now()print end_time-start_time
结果为:
91752141
0:00:00.299000
但是结果好像不对。怎么回事呢?
...
2居然也是abundant。。。我怎么算的啊。。不可以这样啊。。
改了下:
#coding=utf-8import math,datetimedef factor(num):    relist=[]    for temp in xrange(1,min(int(math.sqrt(num)+2),num)):        if not num%temp:            if temp==1:                relist.append(1)            else:                relist.extend([temp,num/temp])    return relistdef isabundant(num):    factorlist=factor(num)    if reduce(lambda x,y:x+y,factorlist)>num:        return True    else:        return Falsestart_time=datetime.datetime.now()maxint=28133t_list=[0]*(maxint+1)#要遍历的数据abundantlist=[]for tempint in xrange(2,maxint+1):    if t_list[tempint]==1:        continue    if isabundant(tempint):         t_list[tempint]=1         for value in  abundantlist:             if tempint+value<=maxint:                 t_list[tempint+value]=1         abundantlist.append(tempint)count=0for key,item in enumerate(t_list):    if item==0:        count+=keyprint countend_time=datetime.datetime.now()print end_time-start_time
结果为:
192399088
0:00:00.528000

但是还是错了。。艹 了。
后面居然发现

4,6居然也是abundant了?

估计是我添加了两次约数吧
再改下:

#coding=utf-8import math,datetimedef factor(num):    relist=[]    for temp in xrange(1,min(int(math.sqrt(num)+2),num)):        if not num%temp:            if temp==1:                relist.append(1)            else:                relist.extend([temp,num/temp])    return list(set(relist))def isabundant(num):    factorlist=factor(num)    if reduce(lambda x,y:x+y,factorlist)>num:        return True    else:        return Falsestart_time=datetime.datetime.now()maxint=28133t_list=[0]*(maxint+1)#要遍历的数据abundantlist=[]for tempint in xrange(2,maxint+1):    if t_list[tempint]==1:        continue    if isabundant(tempint):         t_list[tempint]=1         for value in  abundantlist:             if tempint+value<=maxint:                 t_list[tempint+value]=1         abundantlist.append(tempint)count=0for key,item in enumerate(t_list):    if item==0:        count+=keyprint countend_time=datetime.datetime.now()#print abundantlistprint end_time-start_time
结果为:
133317333
0:00:00.291000

还是错了?

.结果还是发现出了自己的问题。错在哪里就不说了。

#coding=utf-8import math,datetimedef factor(num):    relist=[]    for temp in xrange(1,min(int(math.sqrt(num)+2),num)):        if not num%temp:            if temp==1:                relist.append(1)            else:                relist.extend([temp,num/temp])    return list(set(relist))def isabundant(num):    factorlist=factor(num)    if reduce(lambda x,y:x+y,factorlist)>num:        return True    else:        return Falsestart_time=datetime.datetime.now()maxint=28133t_list=[0]*(maxint+1)#要遍历的数据abundantlist=[]for tempint in xrange(2,maxint+1):    #1表示该数过剩,2表示该数可被两个过剩数相加    if isabundant(tempint):         if t_list[tempint]!=2:             t_list[tempint]=1         abundantlist.append(tempint)         for value in  abundantlist:             if tempint+value<=maxint:                 t_list[tempint+value]=2#count=0for key,item in enumerate(t_list):    if item!=2:        count+=key#        print key,printprint count#printend_time=datetime.datetime.now()#print abundantlistprint end_time-start_time
结果为:
4179871
0:00:04.349000

这次结果是对了,但是太慢了。真的。

看下其他人的吧。
。。看了其他。。好像都差不多

#coding=utf-8import math,datetimedef factor(num):    relist=[]    for temp in xrange(1,min(int(math.sqrt(num)+2),num)):        if not num%temp:            if temp==1:                relist.append(1)            else:                relist.extend([temp,num/temp])    return list(set(relist))def isabundant(num):    factorlist=factor(num)    if reduce(lambda x,y:x+y,factorlist)>num:        return True    else:        return Falsestart_time=datetime.datetime.now()maxint=28133t_list=[0]*(maxint+1)#要遍历的数据abundantlist=set( [tempint for tempint in xrange(2,maxint+1) if isabundant(tempint)])#1表示该数过剩,2表示该数可被两个过剩数相加set1=set([ beginvalue+secondvalue for beginvalue in abundantlist for secondvalue in abundantlist])set2=set(range(maxint+1))-set1count=reduce(lambda x,y:x+y,set2)printprint count#printend_time=datetime.datetime.now()#print abundantlistprint end_time-start_time
这是改了之后的。但是我发现。我这个更慢了?
4179871
0:00:08.661000
这是因为循环开销的缘故吗?
再改了下终于降到8秒以下了。
#coding=utf-8import math,datetimedef factor(num):    reset=set()    for temp in xrange(1,min(int(math.sqrt(num)+2),num)):        if not num%temp:            if temp==1:                reset.add(1)            else:                reset.update({temp,num/temp})    return resetdef isabundant(num):    factorset=factor(num)    if reduce(lambda x,y:x+y,factorset)>num:        return True    else:        return Falsestart_time=datetime.datetime.now()maxint=28133t_list=set(range(maxint+1))#要遍历的数据abundantlist={tempint for tempint in t_list if  tempint>=2 and  isabundant(tempint) }#1表示该数过剩,2表示该数可被两个过剩数相加time1=datetime.datetime.now()print time1-start_timeset1={ beginvalue+secondvalue for beginvalue in abundantlist for secondvalue in abundantlist}time2=datetime.datetime.now()print time2-time1set2=t_list-set1count=reduce(lambda x,y:x+y,set2)printprint count#printend_time=datetime.datetime.now()#print abundantlistprint end_time-start_time
结果为:

0:00:00.326000
0:00:04.288000


4179871
0:00:04.615000

牛人的代码:

def PE023(limit = 28123):  somDiv = [1] * (limit+1) # jusk 28123 inclus  for i in range(2, int(limit**.5)+1):    somDiv[i*i] += i    for k in range(i+1, limit//i+1):        somDiv[k*i] += k+i  abondant, res = set(), 0  ajout = abondant.add  for n in range(1, limit+1):    if somDiv[n]>n: ajout(n)    if not any( (n-a in abondant) for a in abondant ): res+=n  return res


0 0