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-8
import math,datetime
def factor(num):
relist=[1]
for temp in xrange(2,int(math.sqrt(num)+2)):
if not num%temp:
relist.extend([temp,num/temp])
return relist
def isabundant(num):
factorlist=factor(num)
if reduce(lambda x,y:x+y,factorlist)>num:
return True
else:
return False
start_time=datetime.datetime.now()
maxint=28133
t_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=0
for key,item in enumerate(t_list):
if item==0:
count+=key
print count
end_time=datetime.datetime.now()
print end_time-start_time
结果为:
91752141
0:00:00.299000
但是结果好像不对。怎么回事呢?
...
2居然也是abundant。。。我怎么算的啊。。不可以这样啊。。
改了下:
#coding=utf-8
import math,datetime
def 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 relist
def isabundant(num):
factorlist=factor(num)
if reduce(lambda x,y:x+y,factorlist)>num:
return True
else:
return False
start_time=datetime.datetime.now()
maxint=28133
t_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=0
for key,item in enumerate(t_list):
if item==0:
count+=key
print count
end_time=datetime.datetime.now()
print end_time-start_time
结果为:
192399088
0:00:00.528000
但是还是错了。。艹 了。
后面居然发现
4,6居然也是abundant了?
估计是我添加了两次约数吧
再改下:
#coding=utf-8
import math,datetime
def 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 False
start_time=datetime.datetime.now()
maxint=28133
t_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=0
for key,item in enumerate(t_list):
if item==0:
count+=key
print count
end_time=datetime.datetime.now()
#print abundantlist
print end_time-start_time
结果为:
133317333
0:00:00.291000
还是错了?
.结果还是发现出了自己的问题。错在哪里就不说了。
#coding=utf-8
import math,datetime
def 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 False
start_time=datetime.datetime.now()
maxint=28133
t_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=0
for key,item in enumerate(t_list):
if item!=2:
count+=key
# print key,
print
print count
#print
end_time=datetime.datetime.now()
#print abundantlist
print end_time-start_time
结果为:
4179871
0:00:04.349000
这次结果是对了,但是太慢了。真的。
看下其他人的吧。
。。看了其他。。好像都差不多
#coding=utf-8
import math,datetime
def 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 False
start_time=datetime.datetime.now()
maxint=28133
t_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))-set1
count=reduce(lambda x,y:x+y,set2)
print
print count
#print
end_time=datetime.datetime.now()
#print abundantlist
print end_time-start_time
这是改了之后的。但是我发现。我这个更慢了?
4179871
0:00:08.661000
这是因为循环开销的缘故吗?
再改了下终于降到8秒以下了。
#coding=utf-8
import math,datetime
def 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 reset
def isabundant(num):
factorset=factor(num)
if reduce(lambda x,y:x+y,factorset)>num:
return True
else:
return False
start_time=datetime.datetime.now()
maxint=28133
t_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_time
set1={ beginvalue+secondvalue for beginvalue in abundantlist for secondvalue in abundantlist}
time2=datetime.datetime.now()
print time2-time1
set2=t_list-set1
count=reduce(lambda x,y:x+y,set2)
print
print count
#print
end_time=datetime.datetime.now()
#print abundantlist
print 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