算法训练 连续正整数的和
原创
©著作权归作者所有:来自51CTO博客作者mb614decb9ad0b0的原创作品,请联系作者获取转载授权,否则将追究法律责任
算法训练 连续正整数的和
时间限制: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;
}