C++ Code
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数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,需要求出 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
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
/***********************************************************************************
总体思路: 因为奇数的最大奇数约数就是自己啊,对于偶数我们只能一直除2直到得到一个奇数即为最大奇数约数 比如1 2 3 4 5 6 7 8 9 10 即n = 10 ,此时奇数有1 3 5 7 9 我们把这几个奇数相加然后n / 2 得到第二轮序列序列 1 2 3 4 5 分别对应上次的2 4 6 8 10 五个偶数,这是我们再加1 3 5 依次类推 细节问题: 当n为偶数,就有n / 2个奇数,根据等差数列求和公式 即((首项 + 末项)*项数) / 2, 我们知道n / 2个奇数和为((1 + n - 1)*n / 2) / 2, 即为(n / 2) * (n / 2), 此时n为偶数,因此(n / 2) * (n / 2) = ((n + 1) / 2) * ((n + 1) / 2) 当n为奇数,有(n + 1) / 2个奇数,此时奇数和为((n + 1) / 2) * ((n + 1) / 2) **************************************************************************************/ #include<stdio.h> #include<stdlib.h> #include<math.h> int main(void) { int i,n; int sum = 0; printf("请输入数i\n"); scanf("%d", &i); for (n = i; n > 0; n = n / 2) { sum = sum + (n + 1) * (n + 1) / 4; //printf("%d", sum); } printf("%d\n", sum); system("pause"); }
方法2:
1.判断n是否为奇数,如果为奇数,求所有奇数的和
2.如果为偶数,求最后一个偶数的最大质约数,在求前n-1的奇数和
3.在n减半,依次循环求和
最后时间复杂度为lg(n)到lg(n)*lg(n)之间
C++ Code
|