連續數的和

2022-08-30 18:09:15 字數 1810 閱讀 2960

題面描述

對於乙個給定的正整數 n ,請你找出一共有多少種方式使 n 表示為若干個連續正整數的和,要求至少包括兩個正整數。如 n=15 時,可以有 3 種方式:( 1+2+3+4+5 ),( 4+5+6 ),( 7+8 )。

輸入資料

輸入資料第一行為乙個正整數 t ,表示測試資料的組數。 隨後的 t 行中,每行包括一組測試資料,為乙個整數 n(1≤t≤1000,n≤10^9)。

輸出資料

對每一組輸入資料,輸出一行結果 」case #id: m」 ,表示第 id 組資料的結果是 m , id 從 1 開始。

樣例輸入23

15樣例輸出

case #1: 1

case #2: 3

方法一:

思路:對於乙個給定的數n,例如22,設定兩個指標 i,j     則所求為 sum(i,j) = i+(i+1)+(i+2)+...j =n   其每乙個數必定小於等於n/2 +1 ,若非如此,無論怎麼加都會超過原來的數。   那麼就可以迴圈判斷 sum(i,j) 與 n 的關係:

當 sum(i,j) ==n 時,得到乙個個結果。

當 sum (i, j) < n 時,說明還不夠,j往後一位變成j+1,此時sum = sum + j +1。

當 sum(i,j) > n時,說明過了,此時i往後移一位,變成i+1。此時 sum = sum -i。

直到 i >= j 或者 j > n/2+1。       

1 #include2

3using

namespace

std;45

6int function(intn)7

22else

if (sum 2327

else

if (sum >n)

2832}33

return

count;34}

3536

intmain()

3746

47for (i = 1; i <= n; ++i)

4851

52return0;

5354 }

此程式效率極低。。。提交後超出時間限制。。。

方法二:

利用等差數列

an = a1+(n-1)d    這裡公差d = 1

所以 an = a1+n-1

sn = (a1+an)n/2 = (2a1+n-1)n/2

我們輸入的數就是sn  ,我們要找的是以a1開始遞增的數列使其和為sn

這裡我們可以用迴圈來判定,給定乙個n,sn已知,就可以求出a,如果a為正整數那麼就可以找到等差數列的首項,加上n給定,d=1,那麼就可以寫出這個和式子。

注意,這裡的n無須一直從2開始列舉下去,可以由sn = (a1+an)n/2 = (2a1+n-1)n/2,所以a1=sn/n-n/2+1/2,該式子為遞減函式,n越大,a越小,而a最小為1,故另a=1時可確定n的最大範圍。

令a=1,得二元一次方程(1/2+n/2)*n=sn ,即n^2+n-2*sn =0,可得方程兩個根中取較大的根n=0.5*(-1+sqrt(1+8*sn )),從而確定n的最大列舉範圍。

#include#include

using

namespace

std;

int function(int

n) }

return

count;

}int

main()

for (i = 1; i <= n; ++i)

system(

"pause");

return0;

}

連續數的和

題目 時間限制 1 sec 記憶體限制 128 mb 提交 317 解決 99 給出兩個整數n和k,2 n 70000,1 k n 求出1,2,3,n中連續k個數的和,並計算出和為平方數的個數。例如n 10,k 3。在1,2,10中,連續3個數的和有 1 2 3 6 2 3 4 9 3 4 5 12...

連續自然數和

題目描述 對乙個給定的自然數m,求出所有的連續的自然數段,這些連續的自然數段中的全部數之和為m。例子 1998 1999 2000 2001 2002 10000,所以從1998到2002的乙個自然數段為m 10000的乙個解。輸入輸出格式 輸入格式 包含乙個整數的單獨一行給出m的值 10 m 2,...

連續自然數和

題目描述 描述 description 對乙個給定的自然數m,求出所有的連續的自然數段 連續個數大於1 這些連續的自然數段中的全部數之和為m。例子 1998 1999 2000 2001 2002 10000,所以從1998到2002的乙個自然數段為m 10000的乙個解。輸入輸入格式 input ...