1. 程式人生 > >關於連續自然數和問題的探討

關於連續自然數和問題的探討

題目描述:
對一個給定的自然數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; }