zoukankan      html  css  js  c++  java
  • [原]编程之美2.21 只考加法的面试题

    题目如下:
    --------------------------------------------------
    看了这么多题目,有人不禁会想,这些题目都太难了!有没有容易的?这里有一题,只用到加法,大家别嫌题目简单,不妨试试看。
    我们知道:
    1+2=3
    4+5=9
    2+3+4=9
    等式左边都是两个以上连续的自然数相加,那么是不是所有的整数都可以写成这样的形式呢?稍微考虑一下,我们发现,4、8等数并不能写成这样的形式。
    问题1:写一个程序,对于一个64位正整数,输出它所有可能的连续自然数(两个以上)之各的算式。
    问题2:大家在测试上面程序的过程中,肯定会注意到一些数字不能表达为一系列连续的自然数之和,例如32好像就找不到。那么,这样的数字有什么规律呢?能否证明你的结论?
    问题3:在64位正整数范围内,子序列数目最多的数是哪一个?这个问题要用程序蛮力搜索,恐怕要运行很长时间,能否用数学知识推导出来?
    --------------------------------------------------

    我的解答

    解答1:

    程序就不写了,基本思路就是对于给定的数N,遍历2~N的数,满足条件就输出。这样的话复杂度是O(N)
    做一些优化,发现 i = 2~N 增长到一定程度后,会出现其边缘序列已经超出整数范围,故后面的值不用再遍历,可直接退出循环。
    这样优化后,测试发现N=10^7时需循环4470次,比O(N)好了许多。
    进一步进行理论分析如下:
    设N = k*m ,k表示k个数之和,m表示序列的中点数(若k为偶数则m的小数部分必须为0.5才有解)
    由于序列起点至少为1,所以有
    m - (k + 1)/2 >= 0 (*)
    将 m = N/k 代入上式,整理得 k^2 + k - 2*N <=0,解得 0 < k <= ( sqrt(1 + 8 * N) - 1) / 2
    不等式右侧就是k取值的上界,由此可将算法改进,时间复杂度降为O(sqrt(N))
    解答2:
    严格证明,我是不会呵,阐述下思路吧
    先说下我的答案,是2的幂次的数均不可。
    证明如下:
    (1)奇数都可以,因为任意奇数都可以拆为k + (k + 1)的形式,从而有解
    (2)由对称性可知,凡是能被2整除的偶数,均不能表示为两个数之和的形式,推广得对于数N,若要将其表示为长度k的序列(当然k不能超过上述解答1的上界),必须有
    N % k == k/2,该式其实与N被偶数除,结果小数部分必须为0.5是等价的
    可知,对于任意数N,若可以表示为2^x * y,y表示除2以外因子的乘积,则在k满足上界限制的前提下,k = 2^(x+1)一定有解。
    反推之,对于任意2的幂次的数,均无解。
    解答3:
    由解答1可知,k的上界与N有关,N越大则k的取值范围越大,可能的序列数目就越多。
    因此,由贪心策略得,最大值MAX应具有如下形式
    MAX = 3^n
    由于是64位整数,有
    3^n < 2^64
    解得
    n < (ln2/ln3)*64 ,n是整数,n最大值是40
    所以有MAX = 3^40
    再由解答1得,序列数最多为20*2 = 40个
  • 相关阅读:
    my ReadBook_dianzishangwu / 2020216 / dianzishangwuwuliu
    my ReadBook_shichangyingxiao / 2020208
    C#编写的clock
    Java建立JProgressBar
    java基本类型byte的取值范围
    正则表达式整理大全
    (C#)如何利用Graphics画出一幅图表
    设置鼠标可以移动窗体
    Java编程提高性能的26个方法
    数据加密工具设计经验
  • 原文地址:https://www.cnblogs.com/peteryj/p/1944889.html
Copyright © 2011-2022 走看看