编程之美 -- 只考虑加法的面试题,程序理解和分析

先考虑-- 只考虑加法的面试题

题目:

有些自然数可以表示为几个连续的自然数之和,例如
3 = 1+2
9 = 4+5
9 = 2+3+4

输出所有64位正整数。连续自然数的和。
现在想知道在64位正整数范围内,子序列数目最多的数是哪一个?例如9就有两种子序列表示,它的子序列数目为2,这个问题能否用数学而不是蛮力的方法计算出来呢?

以下思路来自:http://bbs.csdn.net/topics/210084060

设n写成的连续的自然数以a开头,以b结尾。则,长度为b-a+1.
由求和公式,得:(b-a+1)*(b+a)/2=n
=> (b-a+1)*(b+a)=2n
因为b-a和a+b是同奇偶的,于是(b-a+1)和(b+a)一奇一偶。

若n=2^k2 * 3^k3 * 5^k5 * ... * n^kn.
于是,n写成连续自然数之和形式的个数是:m=3^k3 * 5^k5 * ... * n^kn的真因子个数。----》没看懂!!!!
而3^k3 * 5^k5 * ... * n^kn的因子个数是:(k3+1)*(k4+1)*...*(kn+1).

于是,我们现在只要求在64位正整数范围内,形式为3^k3 * 5^k5 * ... * n^kn(偶数可以不用考虑了),且(k3+1)*(k4+1)*...*(kn+1)最大的数.

这个问题呢,其实在ACM中经常出现,一些题目称其为“反素数”。

反素数的性质:

性质一:一个反素数的质因子必然是从2开始连续的质数.
性质二:p=2^t1*3^t2*5^t3*7^t4.....必然t1>=t2>=t3>=....



对我们这个题目来说,m=3^k3 * 5^k5 * ... * n^kn,质因子是从3开始,且k3>=k5>=k7>=...>=kn。
对64位整数范围来说,最多只需要14个素数构造:3,5,7,11,13,17,19,23,29,31,37,41,47,51.
这样,我们就可以利用k3>=k5>=k7>=...>=kn这个条件来搜索解了。
具体算法可以用回溯法,附加一些剪枝操作,可以很快出解了。

在64位正整数范围内,子序列数目最多的数是13835020108241056725,它可表示为:3^3*5^2*7*11*13*17*19*23*29*31*37*41*43*47. 
它可写成的子序列数目是4*3*2^12=3*2^14=49152个。


二 程序理解和时间分析 

using System;
using System.Collections.Generic;
using System.Text;
 
namespace FindTheNumber
{
     class Program
     {
          static void Main(string[] args)
          {
               int [] rg =
               {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};
 
               for(Int64 i = 1; i < Int64.MaxValue; i++)
               {
                    int hit = 0;
                    int hit1 = -1;
                    int hit2 = -1;
                    for (int j = 0; (j < rg.Length) && (hit <= 2); j++)
                    {
                          if((i % rg[j]) != 0)
                          {
                               hit++;
                               if(hit == 1)
                               {
                                    hit1 = j;
                               }
                               else if (hit == 2)
                               {
                                    hit2 = j;
                               }
                               else
                                    break; 
 
                          }
                    }
 
                    if((hit == 2) && (hit1 + 1 == hit2))
                    {
                          Console.WriteLine("found {0}", i);
                    }
 
               }
          }
     }
} 

1> 这个程序要找的是符合什么条件的数?
2> 这样的数存在么?符合这一条件的最小的数是什么?
3> 在电脑上运行这一程序,你估计要多长时间才能输出第一个结果?时间精确到分钟(电脑配置:单核CPU2.0GHz,内存和硬盘资源充足)

个人解答:

首先:题目的意思是找出俩个相邻的数,不能被整除,但其他的数(28个)能被整除!

大家先看这个看看会有什么想法   Z=2^k2 * 3^k3 * 5^k5 * ... * n^kn. 


题中除数:{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};

其中的素数有:2,3,5,7,11,13,17,19,23,29,31

 整数 由 Z=2^k2 * 3^k3 * 5^k5 * ... * n^kn.   

但是28个数都能被整除,俩个例外,需找由素数组合的形式最小的不能被整除的。

可以试,或直接折中,31/2   = 15 所以找16以上的素数必然没有公约数,小的可以试肯定有至少2的倍数比如3,11,13-- 》6,22,26!

这个数就是17  --- 17为素数 所以连续的即16,17不能被整除

再利用:Z=2^k2 * 3^k3 * 5^k5 * ... * n^kn. 

从上可知28个数都能被整除,俩个例外,只需有28个数中的素数组合,去除17即可

2,3,5,7,11,13,19,23,29,31 

 Z=2^3*3^3*5^2*7*11*13*19*23*29*31。  

不能是16的倍数,故要得到8,至少要3个2。要得到27至少要3个3,要得到25,至少要2个5,其余的素因子都只需一个就够了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值