网易2017年校招笔试题 最大的奇约数

Posted wangxiaobao的博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网易2017年校招笔试题 最大的奇约数相关的知识,希望对你有一定的参考价值。

题目:

定义函数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 + 7 = 21.

 

分析:

奇数的最大约数是自身, 偶数的最大约数是是除去所有偶因子之后的那个奇数。所以直观的思路就是挨个遍历一遍加起来。

代码:

 1 #include <iostream>
 2 using namespace std;
 3 int main() {
 4     long long N;
 5     cin >> N;
 6     long long result = 0;
 7     for (long long i = 1; i <= N; ++i) {
 8         int temp = i;
 9         while (temp % 2 == 0) {
10             temp /= 2;
11         }
12         result += temp;
13     }
14     cout << result << endl;
15     return 0;
16 } 

然而, N的取值范围时10^10,所以O(n)的算法是超时的。

考虑优化,设sum(i) = f(1) + f(2) + ... + f(i);

求sum(i)的过程中,所以f(i), i 为奇数可以直接求,就是 i 本身。

问题就是求所有f(i), i为偶数的和。

因为是最大奇约数,所以f(2k) = f(k),所以f(2) + f(4) + ... + f(2k) = f(1) + f(2) + ... + f(k);

所以

sum(i) =  sum (i / 2) + 1 + 3 + ... + i - 1  (i 为偶数)

          =  sum (i - 1) + i (i 为奇数)

时间复杂度O(logn),可以解决。

 1 #include<iostream>
 2 using namespace std;
 3 long long sum(long long n) {
 4     if (n == 1) {
 5         return 1;
 6     }
 7     if (n % 2 == 0) {
 8         return  sum(n / 2) + n * n / 4;
 9     }
10     else {
11         return sum(n - 1) + n; 
12     }
13 }
14 int main() {
15     int N;
16     cin >> N;
17     cout << sum(N) << endl;
18 }

 

以上是关于网易2017年校招笔试题 最大的奇约数的主要内容,如果未能解决你的问题,请参考以下文章

网易2019校招笔试题-瞌睡

网易2017秋招笔试题3:最长公共子括号序列长度

微软2017校招笔试题2 composition

算法题 144:线性结构完全二叉树等5道题(努比亚2017校招笔试题)

微软2017校招笔试题3 registration day

小米2017校招笔试题