10届国赛java试题 E: 序列求和

试题 E: 序列求和


【问题描述】
学习了约数后,小明对于约数很好奇,他发现,给定一个正整数 t,总是可
以找到含有 t 个约数的整数。小明对于含有 t 个约数的最小数非常感兴趣,并
把它定义为 S t 。
例如 S 1 = 1, S 2 = 2, S 3 = 4, S 4 = 6,···。
现在小明想知道,前 60 个 S i 的和是多少?即 S 1 + S 2 + ··· + S 60 是多少?
思路:
这到和问S100的约数是什么差距还是很大的因为约数是质数的时候他们的数是比较大的,我网上找了分解质因数的数论上的知识,他们说的是如果约数是质数时要求最小数的话那么就是2的那个的质数减一次方。比如S13 ,那么他的最小数就是2**12.
我们可以看出如果s不是质数的话那么我们的求法就是如何才可以乘到和约数相等, 我们说一个数的分解因数的指数减一在和他们的相乘就是那个数的约数。所有我们可以反着推如:

s12=  2*2*3  =   3*2*2   =  3*4  =  4*3  
2**(3-1)*3**(2-1)*5**(2-1)=60  约数求对应的数。
我们先把12的分解因数表示 一个数的分解质数的指数
如:60 2**2*3*5 这是一个数的分解质数  我们求60的约数就是 指数加一相乘   (2+1)*(1+1)*(1+1)=12
所以我们就知道可以用约数来求那个最小数,我们可以先把约数的分解因数全部求出来然后在算出最小数就可以算出对应的最小数了。

      

答案:292809912969717649
程序:

def z(a):  #判断质数
    if a==2 or a==3:
        return 1
    if a%2==0  or a==1:
        return 0
    k=1
    while k*k<=a:
        k+=2
        if a%k==0:
            return 0
    return 1
b=[]
for p in range(2,1000):
    if z(p):
        b.append(p)
m=[0 for i in range(61)]
def san(a,a1):
    global k
    if  z(a) or a==1:
        a1+=str(a)+" "
        p=0
        k1=a1.split(" ")
        k1.pop()
        d=1 
        for i  in k1:
            d*=b[p]**(int(i)-1)
            p+=1
        if k==1:
            k=d
        k=min(k,d)
        return k
    for i in range(2,60):
        if i>a:
            break
        if a%i==0:
            san(a//i,a1+ str(i)+" ")

for i in range(1,60+1):
    k=1
    san(i,"")
    m[i]=k

print(sum(m))

禁止转载。仅用于自己学习。对程序错误不负责。

猜你喜欢

转载自blog.csdn.net/weixin_46640345/article/details/112981360
今日推荐