转自:http://www.blker.com/?p=745
问题:
将正整数拆分为连续自然数之和
公式:
连续的自然数之和让我们想到了等差数列求和公式:
注:其中Sum为要分解的正整数,n为连续自然数的个数,aFirst为连续自然数的第一位数
将以上公式改写成另外一种格式
注:求解得到连续自然数个数n:
如果一个数可以分解为几个连续自然数之和,那么就意味着方程有解,那么对于相应的解就有如下限制,
必须为平方数且开根号的结果必须为奇数
需要注意的:由于是连续自然数,所以首项aFirst必定不可能大于n/2,所以不需要从1-n遍历,只需要从1- n/2 遍历即可。
01 | // partitionSum.cpp : Defines the entry point for the console application. |
02 | // |
03 |
04 | #include "stdafx.h" |
05 | #include <math.h> |
06 |
07 | int main(int argc, char* argv[]) |
08 | { |
09 | // 等差数列求和公式 Sum = n*aFirst + n*(n-2)/2; |
10 | // Sum 为要拆分的整数, |
11 | // n 为拆分后连续自然数个数 |
12 | // aFirst 为连续自然数中的第一位数 |
13 |
14 | int Sum, aFirst; |
15 | int i,j; |
16 | int w,k,m; |
17 | printf("请输入要分解的自然数Sum: "); |
18 | scanf("%d",&Sum); |
19 | printf("/n"); |
20 |
21 | for(i = 1; i <= Sum/2; i++) //由于是连续自然数,所以首项必定不可能大于n/2 |
22 | { |
23 | aFirst = i; |
24 | w = (2*aFirst-1) * (2*aFirst-1) + 8*Sum; |
25 | k = (int)sqrt(w); |
26 | m = k - 2*aFirst + 1; |
27 | if(k*k != w) // k是一个平方数 |
28 | continue; |
29 | else if(m %2 !=0) // m必须为偶数 |
30 | continue; |
31 | else |
32 | { |
33 | printf("可以分解%d个连续自然数:/n",m/2); |
34 | for(j=1;j<=m/2;j++) |
35 | printf("%d ",i+j-1); |
36 | printf("/n/n"); |
37 | } |
38 | } |
39 |
40 | return 0; |
41 | } |
效果如下:
本文介绍了一种算法,用于将一个给定的正整数拆分为若干连续自然数的和,并提供了具体的实现代码。通过等差数列求和公式,推导出了判断一个数是否能被拆分的条件。




3074

被折叠的 条评论
为什么被折叠?



