最大奇约数

题目:
给定一个数,如10,它的约数是1,2,5,10,最大奇约数就是5,(约数里面最大的那个奇数),现在给定一个n,求1-n内每个数的最大奇约数的和。
如输入:
7
则计算1,2,3,4,5,6,7的奇约数之和=1+1+3+1+5+3+7=21
输出:
21
idea:很明显,奇数的最大奇约数就是它本身,关键是偶数的最大奇约数怎么快速求出.
一般,一个偶数不断除以2,直到是奇数为止,这就是它的最大奇约数——会超时的,如果改成右移,会降低一点时间复杂度,但也不是最好的,因为做了很多重复计算(比如算50,100,200的时候,100/2=50,200/2=100)
那么,比较好的一个方法是什么呢?
化除为乘.
即:得到一个奇数以后,对它不断乘以2,可以得到一系列的偶数,这些偶数的最大奇约数都是刚开始的那个奇数。看到这个算法的时候我也是惊呆了,真帅。。赶快记下来
举个栗子:
算1-10的最大奇约数之和
从1开始
result=1
1*2 = 2
result = 1+1
2*2 = 4
result = 1+1+1
4*2=8
result = 1+1+1+1
8*2>10 pass
3:
result = 1+1+1+1+3
3*2=6
result = 1+1+1+1+3+3
6*2=12 pass
5:
result = 1+1+1+1+3+3+5
5*2=10
result = 1+1+1+1+3+3+5+5
7
result = 1+1+1+1+3+3+5+5+7
9
result = 1+1+1+1+3+3+5+5+7+9
所以,最终的奇约数之和为 36

#coding: utf-8
# Python 2.7
def sum_of_max_odd_divisor(n):
    result = 0
    for i in range(1,n+1,2):
        result += i
        j = i * 2
        while j <= n:
            result += i
            j *= 2
    return result

ps.还是很佩服。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值