zoukankan      html  css  js  c++  java
  • 每日编程系列———最大奇约数

    一、题目

    小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题: 定义函数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)
    输入例子:
    7
    输出例子:
    21
    二、答案解析
    刚读完题,小编马上就有了思路,还有点小得意,写完之后,然后进行了代码测试,谁曾想,算法因为时间复杂度太大,不能通过测试,当然是不合格喽。
    以下是不合格的算法,思路很单纯,就是从1到n循环,每次循环求出当前数的最大奇约数,然后累加,这个算法在小编的电脑上(2016的13英寸MAC中配)输入了1,000,000,000,然后用了39657ms计算完毕,晕的一逼,算法写成这样也是没谁了


    —————————————华丽的分割线———————————



    正确的姿势是这样的:

    首先,先讨论一下数的奇约数,奇数的最大奇约数就是本身,偶数要不断地除以2,直到除以2的结果是奇数,那么这个结果就是其最大奇约数
    在看我们的题目要求,是求出从1到n之间(包括1和n)的每个数的最大奇约数,然后对它们求和。
    1.当n是奇数时,那么在1到n之间共有(n+1)/2个奇数,根据等差数列求和的理论,sn=(首项+末项)*项数/2,这些奇数的和为(n+1)/2*(n+1)/2;
    2.当n是偶数时,
    那么在1到n之间共有n/2个奇数,这些奇数的和为n/2*n/2,当然在Java中也可以表示为:(n+1)/2*(n+1)/2;
    然后这些只是范围内所有奇数的最大奇约数之和,那么剩余的偶数的奇约数之和怎么求呢,是这样的:
    我们可以让n除以2,然后求出1到n/2范围内的所有奇数的最大奇约数之和,与之前的求和进行累加,如此让n不断地除以2,直到等于0,那么这所有的累加就是要求的数。

    算法的实现如下:








  • 相关阅读:
    运算符
    java--有关前台展示图片流的用法
    TortoiseSVN--Subversion客户端使用详解及问题解决
    SVN 文件的解锁方法
    JDBC中获取数据表的信息
    tomcat配置文件解决乱码问题
    正则表达式常用匹配
    Java:如何选择最为合适的Web开发框架
    键盘enter事件 兼容FF和IE和Opera
    PayPal 支付接口详解
  • 原文地址:https://www.cnblogs.com/coderls/p/6442537.html
Copyright © 2011-2022 走看看