将n分解成连续整数之和

从键盘输入一个数,然后求出连续整数相加使其和刚好和输入的数相等。
如:15=1+2+3+4+5
15=4+5+6
15=7+8
开始想了很久,并且一直在想计算,比如例举所有...这肯定能实现,但是效率不高。后来想起了等差数列来计算。这时候就只要寻找合适了首项以及对应的长度即可。
对于一个L个步长为1首项为a1的等差数列和S=(2a1+L-1)*L/2 ===>L^2-(2a1-1)L-2S=0==>令b=2a1-1 则
L=(-b+sqrt(b^2+8S))/2.
所以此时先判读 delta=b^2+8S是否是完全平方数,是则看delta-b是否能被2整除,如果满足则此时a1满足条件,计算出L,然后从a1打印到a1+L-1即可。上面两个如任何一个不满足则计算下一个a1.
代码如下还请各位大侠帮忙看看啊,是否达到了要求


/****************************************************
* copyright (c) [email protected]
* 2012-08 AT Hunan University
*****************************************************/

#include
#include
#include

/*
* 功能:判断一个整数是否是完全平方数
* 参数:x要判断的整数,*val 所得到开方数
* 返回:是完全平方数返回1,否则返回0
*/
int issqrt(int x,int *val)
{
double s=sqrt((double)x);
double dx=s-(int)s;
*val=(int)s;
return dx<1e-7;
}

/***************************************
* 功能:查找首项a1,以及找到对应的项数L
* 参数:a1要测试的首项,*L求得对应项数,
* a1不适合时为任意值。sum则是输入
* 那个需要分解的总和。
* 返回:a1适合返回1否则返回0
***************************************/
int findfirst(int a1,int *L,int sum)
{
int tem=0;
int delta;
int *sq;
tem=(a1<<1)-1;
delta=tem*tem+8*sum;
sq=(int *)malloc(sizeof(int));
if(issqrt(delta,sq))
{
tem=*sq-tem;
if(!(tem&0x01))
{
*L=tem>>1;
free(sq);
return 1;
}
free(sq);
return 0;
}
free(sq);
return 0;
}

/************************************************
* 功能:打印连续的整数
* 参数:a1连续整数的第一个整数,L整数的个数
* 返回:无
************************************************/
void display(int a1,int L)
{
int i=1;
printf("%d",a1);
for(i=1 ; i {
printf("+%d",a1+i);
}
printf("\n");
}

int main()
{
int a1=1;
int n;
int *L;
L=(int *)malloc(sizeof(int));
printf("Please Input a Integer(>0):");
scanf("%d",&n);
for( a1=1 ; a1< (n>>1)+1 ; a1++)
{
if(findfirst(a1,L,n))
{
printf("%d=",n);
display(a1,*L);
}
}
free(L);
return 0;
}

你可能感兴趣的:(数据结构/算法)