算法训练 连续正整数的和  

时间限制:1.0s   内存限制:256.0MB

    

问题描述

78这个数可以表示为连续正整数的和,1+2+3+...+12,18+19+20+21,25+26+27。
  输入一个正整数
  输出
  对于多种表示法,a小的方案先输出。

样例输入

78

样例输出

1 12
18 21
25 27

分析:首先想到的是写一个函数fx用于求first到last之间所有连续正整数的和,当和等于题目输入n时,就输出相应的first和last值。


int fx(int f,int l)//求first到last所有连续数字之和
{
int sum=0;
if(f>l)
return sum;
else
sum+=fx(f+1,l)+f;
}

想到递归在数据很大的时候会特别的慢,又用循环写了fx函数


int fx(int f,int l)//求first到last所有连续数字之和
{
int sum=0;
while(f<=l)
{
sum+=f;
f++;
}
return sum;
}


主函数:


#include <stdio.h>

int main()
{
int n;
scanf("%d",&n);
int i,j;
for(i=1; i<n/2; i++)
for(j=i+1; j<n/2; j++)
if(fx(i,j)==n)
printf("%d %d\n",i,j);

return 0;
}


但是这样时间上还是过不了的。

换个思路:用a[]数组存储前n项和,比如a[i]存储1到i的和。

那么只需a[j]-a[i]==n,对应的i和j即为满足条件的输出。



#include <stdio.h>
int a[10001];
int main()
{
int n;
scanf("%d",&n);
int i,j;
a[0]=0;
for(i=1; i<=n; i++)
a[i]=a[i-1]+i;//a[i]为前i项和
for(i=1; i<n-1; i++)
for(j=i+1; j<=n; j++)
{
if(a[j]-a[i]==n)//i和j之间数的和等于n
printf("%d %d",i,j);
else if(a[j]-a[i]>n);//重要剪枝,继续只会越加越大
break;
}
}


#include <stdio.h>
int a[10001];
int main()
{
int n;
scanf("%d",&n);
int i,j;
a[0]=0;
for(i=1; i<=n; i++)
a[i]=a[i-1]+i;//a[i]为前i项和
for(i=0; i<=n-2; i++)//注意i从0开始
{
for(j=i+1; j<=n; j++)
{
if(a[j]-a[i]==n)//i和j之间数的和等于n
printf("%d %d\n",i+1,j);
else if(a[j]-a[i]>n)//重要剪枝,继续只会越加越大
break;
}
}
return 0;
}



算法训练 连续正整数的和_i++