问题描述:写一个程序,对于一个64位正整数,输出它所有可能的连续自然数(两个以上)之和的算式。
例如:3=1+2; 9=5+4; 9=2+3+4。
刚开始看到这个题目,直接想到的方法就是蛮力解决:即对于每一个输入的整数,从1开始加,一直加到等于或者大于这个整数为止。如果等于这个整数,则找到了一种连续自然数相加的模式;如果大于这个整数,则无法找到,继续从2开始加,依次类推。例如对于5来说,首先从1开始加:1+2+3=6>5,这样从1开始就无法找到,从而停止继续相加;然后从2开始相加:2+3=5,成功找到。
这是很自然的一种想法,可以达到题目要求。但是,很显然工作量比较大,程序时间复杂度高。于是百度之,找到一种比较好的解决方法,此方法采用了数学分析(数学是个好东西啊),稍微一变换,程序就很简单了。
思路是这样的:
假设这个正整数n可以表示成2个以上的连续自然数之和,那么可以设这个序列为a,a+1....a+i。
那么n=a+(a+1)+...+(a+i)=(i+1)*a + (i+1)*i/2。如果我们可以确定i的范围,那么我们就可以遍历i,对于所有的i的取值,得到对应的a的值,然后判断a是否为整数,即可知是否符合要求。这里i可以认为表示的是序列的长度,那么最长的序列必然是n=1+2...+i。所以有i*(i+1)=2n。
解得i=(sqrt(8n+1)-1)/2,所以i的取值就是[1, (sqrt(8n+1)-1)/2]区间中。随即,遍历i的取值,然后判断对应的a是否为整数即可。
好的,有了思路就可以开始编码了,下面是代码部分: