No_23Non-abundant sums

问题描述:

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值