这是编程之美中的一道题。编程之美中的题目是这样的:

1+2=3

4+5=9

2+3+4=9

等式的左边都是两个或者两个以上的连续自然数相加,那么是不是所有的整数都可以写成这样的形式?

问题1:写个程序,对于一个64位正整数,输出它所有可能的连续自然数之和(两个数以上)的算式。

问题2:哪些数字不能不能表示成连续自然数之和?能否证明。

问题3:在64位正整数的范围内,子序列数目最多的数是哪一个?能否用数学知识推导出来。

-------------------

问题1:

这个最先想到方法就是蛮力法。对于一个i (1<i<n)进行测试,看一i开头的自然数序列是不是能得到n这个和。C#代码如下:

public static void getSequence(int S)
{
  writer.WriteLine("--------"+S+"---------");
  int sum ;
  for (int i = ; i < S; i++)
  {
    sum = ;
  List<int> ns=new List<int>();
  for (int j = i; j <= S&&sum<S; j++)
  {
    sum += j;
    ns.Add(j);
  if (sum == S)
  {
    printArray(ns);
break;
  }
}
}
}

这个算法的时间负责度是O(n*n)级别的。

一些改进可以来对数学公式的应用。

假设这个连续序列为m,m+1,m+2,…,m+k-1,其中m>0,k>1.那么s=(m+m+k-1)*k/2,即2*s=(2*m+k-1)*k.只要找到m和k的值,这个序列就可以求出. m和k有何关系? 容易发现,(2*m+k-1)和k肯定是前者大于后者,并且一个为奇数一个为偶数。因此将2*s进行分解表示为2*s=2^t*a.其中a是个奇数,将a进行因式分解变成a=b*c,那么2*s=2^t*b*c.求出所有2*s的一个奇数和一个偶数的因子分解,就找到了对应的2*m+k-1和k,进而能够解出m和k.

下面是上述思想的java实现。


public void getSequence(int S){
System.out.println("------"+S+"------");

int t=get2(2*S);
int a=(int)(2*S/Math.pow(2, t));
if(a==1){
System.out.println(String.format("%d has no solution", S));
return;
}
ArrayList<Integer[]> pairs=getFactors(a);
for(Integer[] pa:pairs){
for(int i=0;i<2;i++){
int b=pa[i];
int j=(i+1)%2;
int c=pa[j];
int k=0;
int m=0;
k=(int)Math.min(Math.pow(2, t)*b,c);
if(k>1){
m=(int)(Math.max(Math.pow(2, t)*b,c)-k+1)/2;
printSequence(S,m,k);
}
if(b==c){
break;
}
}
}
}

public ArrayList<Integer[]> getFactors(int a){
ArrayList<Integer[]> factorPair=new ArrayList<Integer[]>();
for(int i=1;i<=(int)Math.floor(Math.sqrt(a));i++){
if(a%i==0){
Integer[] pair=new Integer[2];
pair[0]=i;
pair[1]=a/i;
factorPair.add(pair);
}
}
return factorPair;
}

public int get2(int a){
int t=0;
while(a%2==0){
t++;
a=a/2;
}
return t;
}

public void printSequence(int S,int m,int k){
StringBuilder sb=new StringBuilder();
sb.append(S);
sb.append("=");
for(int i=0;i<k;i++){
sb.append(m+i);
sb.append("+");
}
String str=sb.toString();
System.out.println(str.substring(0,str.length()-1));
}

从上面的解的过程,我们也发现了问题2的答案。那就是当n为2的幂次方时,n不能够被分解为这样的连续自然数的和的形式。因为这时n=(m+m+k-1)*k/2是无解的。

关于问题3,看来分解序列最多的生成的a能够分解成不同b*c数最多的那个,注意a是个奇数。64位正整数的范围内,哪个奇数能够产生最多的这样的因式分解?从网上看到这个数应该是3^n这样的形式,因为3是所有质数的最小值,最细刻度的划分,可能会产生最多中划分形式。这样说也有理由,但是不能严谨的证明。而且不用64位,用4位,即n为0到15的正整数,子序列最多的不是9而是15。这样看来3^n不一定正确,但是我觉得这个思路是对的--尽可能的细划分。有时间在研究吧

求输出和为n的所有连续自然数序列的更多相关文章

  1. 输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)

    package leetcode;import edu.princeton.cs.algs4.Cycle;import java.util.ArrayList;import java.util.Arr ...

  2. 输入一个正整数n,输出所有和为n的连续正整数序列

    public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (true) { System. ...

  3. 剑指offer四十一之和为S的连续正数序列

    一.题目   题目描述:小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数 ...

  4. (剑指Offer)面试题41:和为s的连续正数序列

    题目: 输入一个正数s,打印出所有和为s的连续正数序列(至少含有两个数).例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以结果打印出3个连续序列1-5,,4-6和7-8. 思路: ...

  5. 剑指Offer——和为S的连续正数序列

    题目描述: 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久, ...

  6. 剑指Offer - 九度1354 - 和为S的连续正数序列

    剑指Offer - 九度1354 - 和为S的连续正数序列2013-11-23 02:02 题目描述: 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100. ...

  7. Go语言实现:【剑指offer】和为S的连续正数序列

    该题目来源于牛客网<剑指offer>专题. 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数 ...

  8. 【剑指Offer面试编程题】题目1354:和为S的连续正数序列--九度OJ

    题目描述: 小明很喜欢数学,有一天他在做数学作业时,要求计算出9~16的和,他马上就写出了正确答案是100.但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数).没多久, ...

  9. 【剑指Offer】和为S的连续正数序列 解题报告(Python)

    [剑指Offer]和为S的连续正数序列 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-interview ...

随机推荐

  1. Android开发技巧——写一个StepView

    在我们的应用开发中,有些业务流程会涉及到多个步骤,或者是多个状态的转化,因此,会需要有相关的设计来展示该业务流程.比如<停车王>应用里的添加车牌的步骤. 通常,我们会把这类控件称为&quo ...

  2. 使用阿里云Code进行版本控制并配置IDEA

    1.    申请阿里code的账号,网址如下https://code.aliyun.com, 2.    申请完成之后,将账号信息发给项目负责人,由负责人加入项目中 3.    下载git,下载地址为 ...

  3. 洛谷 P2909 [USACO08OPEN]牛的车Cow Cars

    传送门 题目大意: m个车道. 如果第i头牛前面有k头牛,那么这头牛的最大速度会 变为原本的速度-k*D,如果速度小于l这头牛就不能行驶. 题解:贪心 让初始速度小的牛在前面 代码: #include ...

  4. python 函数 hex()

    hex(x)作用:hex() 函数用于将10进制整数转换成16进制整数. x-10进制整数,返回16进制整数 实例: >>>hex(255) '0xff' >>> ...

  5. hadoop之 Zookeeper 分布式应用程序协调服务

    (1) Zookeeper 在 Hadoop 集群中的作用 Zookeeper 是分布式管理协作框架,Zookeeper 集群用来保证 Hadoop 集群的高可用,(高可用的含义是:集群中就算有一部分 ...

  6. 用xshell-ssh连接服务器被经常意外中断

    xshell突然中断报错 Socket error Event: 32 Error: 10053.Connection closing...Socket close. Connection close ...

  7. java.sql.SQLException: No suitable driver

    java.sql.SQLException: No suitable driver at java.sql.DriverManager.getDriver(Unknown Source) at com ...

  8. 分布式开发框架Pebble使用说明

    简介 Pebble定位为一个好用.可靠.高性能.易扩展的分布式开发框架,支持多种使用方式: 使用完整的pebble框架 独立使用各pebble子模块 在其他框架中嵌入pebble框架. Pebble具 ...

  9. Java-Runoob:Java 教程

    ylbtech-Java-Runoob:Java 教程 1.返回顶部 1. Java 教程 Java 是由Sun Microsystems公司于1995年5月推出的高级程序设计语言. Java可运行于 ...

  10. 如何成为java架构师(转载)

    链接:https://www.zhihu.com/question/29031276/answer/54631312 来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 1 ...