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

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. Spring核心AOP(面向切面编程)总结

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/75208354冷血之心的博客) 1.AOP概念: 面向切面编程,指扩 ...

  2. Android代码混淆及项目发布方法记录

     Android代码混淆及项目发布步骤记录 本来整理了一份Android项目混淆与发布的文档,突然想到何不写篇博客,分享一下呢,如是便有了本文. Android代码混淆及项目发布步骤记录 一.清理 ...

  3. [AOP] 6. 一些自定义的Aspect - 方法的重试(Retry)

    前面的一系列文章介绍了AOP的方方面面: AOP的由来以及快速上手 AOP的两种实现-Spring AOP以及AspectJ Spring AOP中提供的种种Aspects - Tracing相关 S ...

  4. centOS 7 tomcat nginx 验证码乱码

    将服务部署在centOS 7上,配置完tomcat和nginx之后,启动服务后,发现验证码这样了~~~ 一开始是以为nginx的原因,但是在Ubuntu系统相同操作发现没有问题,后发现,系统的字体库中 ...

  5. (十七)js bom/dom

    window 是所有BOM中所有对象的核心. window 的属性 window.self代表自己本身,相当于window. eg: console.log(window.self === windo ...

  6. C++11新特性之字节对齐、多参数模版、placement new

    1. 内存对齐 #pragma pack(push, 1) struct A { char a; int b; double c; ]; }; #pragma pack(pop) #pragma pa ...

  7. 《DSP using MATLAB》示例Example7.19

    代码: M = 33; alpha = (M-1)/2; Dw = 2*pi/M; l = 0:M-1; wl = Dw*l; %Hdr = [0, 0, 1, 1]; wdl = [0, 0.6, ...

  8. 剑指offer-第三章高质量代码(树的子结构)

    题目:输入两个二叉树A和B,判断B是不是A的子结构. 思路:遍历A树找到B树的根节点,然后再判断左右子树是否相同.不相同再往下找.重复改过程. 子结构的描述如下图所示: C++代码: #include ...

  9. DataTable / DataSet 与 xml 的相互转换

    之前做DataTable和DataSet转xml一直使用XmlSerializer 序列化完成.今天发现新方法,哇咔咔方便了很多.还不用担心Name为空时报错 static void Main(str ...

  10. 【java反射】Class类型的相关操作演练

    [一]获取范型接口的实现类的范型类型 (1)范型接口 package org.springframework.context; import java.util.EventListener; publ ...