题目:输入一个正整数,若该数能用几个连续正整数之和表示,则输出所有可能的正整数序列。
一个正整数有可能可以被表示为n(n>=2)个连续正整数之和,如: 15=1 2 3 4 5 15=4 5 6 15=7 8
有些数可以写成连续N(>1)个自然数之和,比如14=2 3 4 5;有些不能,比如8.那么如何判断一个数是否可以写成连续N个自然数之和呢?
一个数M若可以写成以a开头的连续n个自然数之和,则M=a (a 1) (a 2) … (a n-1)=n*a n*(n-1)/2,要求a!=0,否则就是以a 1开头的连续n-1个整数了,也就是要求(M-n*(n-1)/2)%n==0,这样就很容易判断一个数可不可以写成连续n个自然数的形式了,遍历n=2…sqrt(M)*2,还可以输出所有解。
代码语言:javascript复制void divide(int num)
{
int i,j,a;
for(i=2; i<=sqrt((float)num)*2; i)
{
if((num-i*(i-1)/2)%i==0)
{
a=(num-i*(i-1)/2)/i;
if(a>0)
{
for(j=0; j<i; j)
cout<<a j<<" ";
}
cout<<endl;
}
}
}
第二个问题是什么样的数可以写成连续n个自然数之和,什么样的数不能?
通过编程实验发现,除了2^n以外,其余所有数都可以写成该形式。下面说明为什么。 若数M符合条件,则有M=a (a 1) (a 2) … (a n-1)=(2*a n-1)*n/2,而2*a n-1与n肯定一个为奇数一个为偶数,即M一定要有一个奇数因子,而所有2^n都没有奇数因子,因此肯定不符合条件。 再证明只有M有一个奇数因子,即M!=2^n,M就可以写成连续n个自然数之和。假设M有一个奇数因子a,则M=a*b。
- 若b也是奇数,只要b-(a-1)/2>0,M就可以写成以b-(a-1)/2开头的连续a个自然数;将这条结论里的a和b调换,仍然成立。15=3*5=1 2 3 4 5=4 5 6.
- 若b是偶数,则我们有一个奇数a和一个偶数b。
- 2.1 若b-(a-1)/2>0,M就可以写成以b-(a-1)/2开头的连续a个自然数。24=3*8=7 8 9.
- 2.2 若(a 1)/2-b>0,M就可以写成以(a 1)/2-b开头的连续2*b个自然数。38=19*2=8 9 10 11.
上述两个不等式必然至少有一个成立,所以可以证明,只要M有一个奇数因子,就一定可以写成连续n个自然数之和。
另一个正整数分解的算法: sum(i,j)为i累加到j的和 令 i=1 j=2 if sum(i,j)>N i else if sum(i,j)<N j else cout i...j
参考代码:
代码语言:javascript复制#include <iostream>
using namespace std;
int add(int m,int n)
{
int sum=0;
for(int i=m;i<=n;i )
sum =i;
return sum;
}
void divide(int num)
{
int i=1,j=2,flag;
int sum=0;
while(i<=num/2)
{
sum=add(i,j);
while(sum!=num)
{
if(sum>num)
i ;
else
j ;
sum=add(i,j);
}
for(int k=i;k<=j;k )
cout<<k<<" ";
i;
cout<<endl;
}
}
int main()
{
int num;
cout<<"Please input your number:"<<endl;
cin>>num;
divide(num);
return 0;
}