天天看點

網易2017秋招程式設計題:最大奇限制 [python]

'''

[程式設計題] 最大的奇約數

時間限制:1秒

空間限制:32768K

小易是一個數論愛好者,并且對于一個數的奇數約數十分感興趣。一天小易遇到這樣一個問題: 

定義函數f(x)為x最大的奇數約數,x為正整數。 例如:f(44) = 11.

現在給出一個N,需要求出 f(1) + f(2) + f(3).......f(N)

例如: N = 7 

f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21

小易計算這個問題遇到了困難,需要你來設計一個算法幫助他。 

輸入描述:

輸入一個整數N (1 ≤ N ≤ 1000000000)

輸出描述:

輸出一個整數,即為f(1) + f(2) + f(3).......f(N)

輸入例子1:

7

輸出例子1:

21

'''

'''

解題思路:找規律

  一開始我很天真地老老實實用問題描述中的方法算,結果當然是逾時超到媽都不認識了。後來靜下心來仔細找了找規律才做出來

  我首先寫出了前30個數的奇約數,并觀察,發現它們似乎所有的數字都是按着1,3,5,7,9...這規律排列的

  仔細一想,便得出了如下規律:

  1~N的數字都可以看成是1,2,4,8...2^log(2,N)的奇數倍數的有序組合

  如              1         2           3           4           5           6          7           8            9

  可看出  1的1倍   2的1個  1的3倍  4的1倍   1的5倍   2的3倍 1的7倍    8的1倍   1的9倍

  找打這個規律後用計算機語言實作,可以把複雜度從O(N),下降到O(logN)

'''

'''

代碼運作結果:

答案正确:恭喜!您送出的程式通過了所有的測試用例

'''

import math
N = int(input())
max_dig = int(math.log(N, 2))
sum_ = 0
for i in range(max_dig+1):
    temp = N//(2**i)
    if temp % 2:
        sum_ +=(1+temp)**2//4
    else:
        sum_ += temp**2//4

print(sum_)