關於連續自然數和問題的探討
阿新 • • 發佈:2018-12-30
題目描述:
對一個給定的自然數M,求出所有的連續的自然數段,這些連續的自然數段中的全部數之和為M。
分析:
(1)常見的方法是暴力去尋找,或者是打表記錄下來,不過很可惜,這樣做的時間複雜度是O(n^2)
(2)利用求和公式和求根公式:
設存在連續自然數,首項為A1,項數為m,即
A1+A2+...+Am=M
得到求和公式
A1*m+m*(m-1)/2=M
整理得到
m^2+(2*A1-1)*m-2M=0
很明顯,這是一個關於m的一元二次方程,利用求根公式
m=(-b+sqrt(b^2-4*a*c)))/(2*a)
帶入得:
m=(1-2*A1+sqrt((2*A1-1)^2+8*M))/2
因為要滿足m為整數,那麼就需要滿足兩個條件:
(1)sqrt((2*A1-1)^2+8*M)是整數;
(2)整個分子為偶數;
如果這兩個條件都滿足,那麼就會存在m,因此可以開一個迴圈,從1遍歷到n/2(想想為什麼),對於每個i,當做A1來處理,看求出來的m是否為整數即可。
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main()
{
int n,tt=1;
while(cin>>n)
{
printf ("Case %d:\n",tt++);
for(int i=0;i<n/2;i++)
{
int a=i;
int w=(2*a-1)*(2*a-1)+8*n;
int k=(int)sqrt(w);
int m=k-2*a+1;
if(k*k!=w)
continue;
else if(m%2)
continue;
else
cout <<i<<" "<<i+m/2-1<<endl;
}
}
return 0;
}