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

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 进阶9:进程通信之 AIDL 解析

    读完本文你将了解: AIDL AIDL 生成文件分析 Stub Proxy AIDL 生成的内容小结 AIDL 的使用回顾 服务端 客户端 小结 手动写个 Binder 首先是定义跨进程接口实现 II ...

  2. Wordpress在主题中自定义登陆页面并且禁用自带的登陆页面

    在使用Wordpress制作主题之后,不想要他自带的登陆页面以及地址. 1.新建一个用户页面来接管与登陆相关的动作 //在主题根目录下新建page-login.php,通过action获取用户动作,然 ...

  3. Android tcpdump 使用

    /************************************************************************** * Android tcpdump 使用 * 说 ...

  4. LeetCode — (1)

    摘要: Nim Game.WordPattern.Move zeros.First Bad version.Ugly Number五个算法的python实现. 一个月多没更新,大概是因为状态一直不太好 ...

  5. 时间由yyyy-MM-dd HH:mm:ss专为yyyy-MM-dd

    (1)类用date 注意:如果用string会报错  页面无法使用string(...): (2)数据库表 (3)页面

  6. Activiti工作流学习之流程图应用详解

    Activiti工作流学习之流程图应用详解 1.目的  了解Activiti工作流是怎样应用流程图的. 2.环境准备2.1.相关软件及版本    jdk版本:Jdk1.7及以上 IDE:eclipse ...

  7. is is not == !=之间的区别

    简单来说,python中的is与is not运算符可判断两个对象是否为同一对象.若为同一个对象,则对象1 is 对象2为True .反正,若非同一个对象,则对象1 is not 对象2为True 要理 ...

  8. gulp 流处理

    包含的内容:     穿插流     流合并     流队列     流筛选 1. 穿插流 // passthrough stream 把流传递给其他的 // use gulp.src(glob,{p ...

  9. IronPython之基本类型

    通过下图展现IronPython的基本类型,便于理解和记忆. 基本数据类型 数据类型 类型 示例 备注 Byte string str ‘hello’ “hello” “””hello””” ‘’’h ...

  10. CentOS6安装vsftpd

    练习:完成vsftpd配置 (1) 禁锢系统用户于家目录 [root@node3 ~]# yum -y install vsftpd [root@node3 ~]# vim /etc/vsftpd/v ...