題面描述
對於乙個給定的正整數 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 #include23using
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#includeusing
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 ...