高斯公式
题目详情:
高斯在上小学时发明了等差数列求和公式: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
#include
#include
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;
}
http://blog.csdn.net/luxiaoxun/article/details/7485291
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;
}
}
}
直接用公式算,C#给你写一个,C++类似做法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Solve(5));
Console.WriteLine(Solve(120));
}
static int Solve(int sum)
{
int r = 0;
for (int i = 1; i <= sum; i++)
{
double x1 = (-1.0 + Math.Sqrt(1 - 4.0 * (i - i * i - 2 * sum))) / 2.0;
double x2 = (-1.0 - Math.Sqrt(1 - 4.0 * (i - i * i - 2 * sum))) / 2.0;
if ((Math.Abs(x1 - (int)x1) < 0.00001 && x1 > 0) || ((Math.Abs(x2 - (int)x2) < 0.00001 && x2 > 0)))
{
r++;
}
}
return r;
}
}
}
2
4
Press any key to continue . . .
思路简单说下。
因为求和公式是 (首项+末项)*项数/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。
你的意思我可能是懂了,我有个思路不知道成不成,大概这样:
public int GetCount(int num)
{
int count=0;//记录种数
int x=0;//临时变量,与num比较
for(int i=1;i<=num/2;i++)
{
for(int j=i;j<num/2+1;j++)
{
x=x+j;//进行从i开始的连续正整数相加,x保存结果
if(x==num)//判断,若x=num,说明找到一种相加的方法
{
count++;//方法数量+1
x=0;x清零
}
}
}
}
这样也不知道对不对,我也是小白,C#入门,楼主试试
public int GetCount(int num)
{
int count=0;//记录种数
int x=0;//临时变量,与num比较
for(int i=1;i<=num/2;i++)
{
for(int j=i;j<num/2+1;j++)
{
x=x+j;//进行从i开始的连续正整数相加,x保存结果
if(x==num)//判断,若x=num,说明找到一种相加的方法
{
count++;//方法数量+1
x=0;x清零
}
}
}
}
程序代码:
#include <stdio.h>
int main(void)
{
int n;
scanf("%d", &n);// 输入要分解的n
for(int n1=1; n1<=n/2; n1++)// n1为最开头的数
{
for(int n2=n1+1; n2<n; n2++)// n2为最末尾的数
{
if((n1+n2)*(n2-n1+1) == n*2)// 用等差数列公式算和
{
//如果相等就输出结果
for(int t=n1; t<=n2; t++)
{
printf("%d,", t);
}
printf("\n");
}
}
}
return 0;
}
你的思路估计是这个