您的位置:首页 > 编程语言

网易2017编程题之前n个数的最大奇约数之和

2017-09-10 10:00 204 查看
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数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个数中,我们可以把任意一个偶数表示成一个奇数和一个偶数的乘积,例如8=23∗1,10=2∗5,18=2∗9,等等。

再扩展一步,前n个数中,任意数都可以表示成:x=2k∗j,k=0,1,2,...,m

这里的x是任意小于等于n的数,j是某一个奇数,那么我们现在看一下m的大小(懒得打公式,也不是很会…):



即m为[log2n]

[]是向下取整符号

这样我们就可以计算每个k对应有多少个j符合要求的,假设为分别为k1,k2,...,km个,再用奇数的前n项和公式,k2i,i=0,1,2,...,m,求和,累计相加即可。下面给出一些例子:



这里只剩下计算每个ki对应的奇数的个数j了。

从上面例子可以看出j的值为([n/2i]+1∗y)/2其中[ ]表示向下取整,y=0,当且仅当 [n/2^i]为偶数,y=1当且仅当[n/2^i]为奇数。下面给出python程序

def get_j_sum(n):
import math
def get_k_j_sum(ki):
return ki**2

def get_j_num(k):
if k%2!=0:
return (k+1)/2
else:
return k/2

m = math.floor(math.log(n, 2))
s=0
for i in range(int(m+1)):
k=math.floor(float(n)/(2**i))
ki=get_j_num(k)
s+=get_k_j_sum(ki)
return int(s)


然而,牛客上我的正确率只有60%,不知道哪位大神帮我找出错误呢???这个在计算100000000的时候与标准答案差了150,望大神指点指点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  编程 网易