高斯公式
题目详情:
高斯在上小学时发明了等差数列求和公式:1+2+..+100=5050。现在问题在于给你一个正整数n,问你他可以表示为多少种连续正整数之和?(自身也算)。
输入格式:
多组数据,每组数据一行,一个正整数n。 0<n<2000000000
输出格式:
每组数据一行,包含一个正整数,表示结果。
答题说明:
输入样例
5
120
输出样例:
2
4
解释:
5=2+3=5
120=1+2+...+15=22+23+24+25+26=39+40+41=120
思路简单说下。
因为求和公式是 (首项+末项)*项数/2
比如1~100,就是(1 + 100)*100 /2 = 5050
所以只要穷举首项,有了首项和和,那么看末项是不是一个大于0的整数就可以了。
设末项是x,有 (i + x)*(x - i + 1)/2=sum,它其实是一个一元二次方程,x^2+x+(i-i^2-2sum)=0,根据公式
x1=-b+sqrt(b^2-4ac)/2 x2=-b-sqrt(b^2-4ac)/2就可以算出x。
#include<stdio.h>
#include<math.h>
//#include<iostream>
//#include<algorithm>
using namespace std;
int n;
void divide(int num)
{
int i,j,a;
int sum=0;
for(i=2; i<=sqrt((float)num)*2; ++i)
{
if((num-i*(i-1)/2)%i==0)
{
//sum+=1;
a=(num-i*(i-1)/2)/i;
if(a>0)
{
//for(j=0; j<i; ++j)
//{
// cout<<a+j<<" ";
//}
sum+=1;
}
// cout<<endl;
}
}
printf("%d\n",sum+1);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
divide(n);
}
return 0;
}
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
void divide(int num)
{
int i,j,a;
int sum=0;
for(i=2; i<=sqrt((float)num)*2; ++i)
{
if((num-i*(i-1)/2)%i==0)
{
//sum+=1;
a=(num-i*(i-1)/2)/i;
if(a>0)
{
for(j=0; j<i; ++j)
{
cout<<a+j<<" ";
}
// sum+=1;
}
cout<<endl;
}
}
//printf("%d\n",sum+1);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
divide(n);
}
return 0;
}
//一开始没看懂提,用二分写了个这
#include<stdio.h>
#include<math.h>
long long n;
void bin()
{
long long low,high,mid,sum;
low=1;
high=n;
while(low<=high)
{
mid=(low+high)/2;
if(mid*(mid+1)/2>n)
high=mid-1;
else
low=mid+1;
}
printf("%lld\n",high);
}
int main()
{
scanf("%d",&n);
bin();
return 0;
}