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

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. Unity中使用柏林噪声生成地图

    孙广东  2017.3.27 http://blog.csdn.NET/u010019717 主要是利用Unity的 Mathf.PerlinNoise   函数(柏林噪声)的不同寻常的功能. htt ...

  2. Windows下修改hosts并且让他立即生效

    1.打开hosts所在的目录 Win+R->C:\windows\System32\drivers\etc 2.编辑hosts文件 使用Notepad++或者记事本以管理员身份打开hosts,修 ...

  3. hibernate的级联(hibernate注解的CascadeType属性)

    [自己项目遇到的问题]: 新增  删除都可以实现 ,就是修改的时候无法同步更新设计三个类:  问题类scask  正文内容类text类    查看数+回复数+讨论数的runinfo类 [正文类和查看数 ...

  4. intellij idea 如何更改比编辑器文本字体和大小

    换上了intellij idea之后,第一件事就是想要改变下文字字体,因为在我这个27寸的2k分辨率的屏幕上,文字显然太小了. intellij idea字体设值分成两部分,一部分是UI部分字体字号设 ...

  5. Hibernate问题集锦: 概述

    Hibernate问题集锦: 概述   ImportNew注: 本文是ImportNew编译整理的Java面试题系列文章之一.你可以从这里查看全部的Java面试系列. Q.怎么配置hibernate? ...

  6. swift 学习-- 元组

    //元组 //定义:元组是有多个值组合而成的复合值,其中的值可以是任意类型,而且每一个元素的类型可以是不同的 let http404Error = (404, "Not Found" ...

  7. mysql各种集群的优缺点

    mysql各种集群的优缺点 1.主从架构:只是有数据备份的功能: 2.主主互备+keepalived:实现数据备份加高可用: 3.主主互备,主主下面分别挂个从: 4.A和B主主互备,把从库都挂到B下, ...

  8. java多线程实现礼花绽放的效果,

    总结:主要是那个红点点在上升的过程中要涂黑色,其实它不是一个点,是一个长条,而是被涂成黑色而隐藏了.还有这个睡眠时间,多线程 是你在面板上随便点,会出现随机的颜色圆圈,点哪里,哪里就可以出现圆 imp ...

  9. mysql replication /mysql 主从复制原理

    一下内容均是根据leader的培训分享整理而成 ************************************我是分割线*********************************** ...

  10. 1127 ZigZagging on a Tree

    题意:中序序列+后序序列构建二叉树,之字形输出其层序序列. 思路:在结点的数据域中额外增加一个layer表示结点所在的层次,并定义vector<int> zigzag[maxn]存放最终结 ...