zoukankan      html  css  js  c++  java
  • 网易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     long long N;
    16     cin >> N;
    17     cout << sum(N) << endl;
    18 }

    有朋友回复可能担心stackoverflow,当时写的时候也觉得可能会递归层数太多,但是提交还是过了的。

    还是可以写成非递归的。

    代码:

     1 #include<iostream>
     2 using namespace std;
     3 long long sum(long long n) {
     4     long long result = 0;
     5     while (n > 0) {
     6         if (n % 2 == 0) {
     7             result += n * n / 4;
     8             n /= 2;
     9         }
    10         else {
    11             result += n;
    12             n--;
    13         }
    14     }
    15     return result;
    16 }
    17 int main() {
    18     long long N;
    19     cin >> N;
    20     cout << sum(N) << endl;
    21 }
  • 相关阅读:
    windows live sync, mesh, skydrive
    忘记SQL SERVER密码的解决
    处理ObjectDataSource调用中DAL层中的异常
    C#中获取应用程序路径的方法(集合)
    datatable复制一行数据到本表
    [Yii Framework] yii中如何在查询的时候使用数据库函数
    [Yii Framework] yii的路由配置
    [Yii Framework] 已经定义的命名空间常量
    [Yii Framework] yii中关于filter
    [Yii Framework] yii中如何不加载layout
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5866351.html
Copyright © 2011-2022 走看看