1. 程式人生 > >一個正整數分解為幾個連續的正整數之和

一個正整數分解為幾個連續的正整數之和

題目: 給定你一個數字 如:15 15可分解為 7+8 4+5+6 1+2+3+4+5 再如: 8 8不可分解為任何連續的正整數之和 所以輸出NONE 此題就是給定一個數字如果這個數字可以分解為幾個連續的正整數之和那麼就輸出所有的形式,如果不能就輸出NONE

今天這道題困擾了我好久,最後發現,一開始求和的時候算錯了。
輸入數n,設定起始位置i,再遍歷連續正整數的長度k,由公式計算出 sum = i + (i+1) + … + (i+k) = (k+1) * (2*i + k) / 2;
而我一開始算出來為k* (2*i + k+1) / 2;
原因是我這樣計算的:
(i+k)*(i+k+1)/2-i*(i+1)/2


而實際上應該是:
(i+k)*(i+k+1)/2-(i-1)*i/2
下面是我最後成功解決這個問題的思路和程式碼:

#include<iostream>  
using namespace std;
/*首先
這道題目可以用到數學中最基礎的等差公式的方式:設給定的數字為S 
S = a1 + a2 + a3 + a4....
S = a1 + a1 + 1 + a1 + 2 + a1 + 3....設一共有i個
S = (a1 + a1 + i - 1) * i /2

首先我們討論那些數不能分解為上面的形式
a1 + a1 + i - 1   和 i  這兩個數肯定要麼一個為偶數要麼一個為奇數(自己腦補)
所以他們成績除2得出的數肯定得有奇數因子,而2^n不可能有奇數因子,所以不能被整除。*/
int IsTwo(int n) { return (n&(n - 1)) == 0 ? 1 : 0; } /*用此函式 n如果為2的n次方那麼他的二進位制表示肯定是第一位為1後面都是0 n - 1恰好是最後一個是1其餘多是0所以n&(n - 1)肯定等於0 所以在這裡我們可以採用位運算&來判定*/ int main() { int num, sum = 0; cout << "請輸入一個正整數:" << endl; cin >> num; if (IsTwo(num)) cout << "NONE"
<< endl; else { for (int i = 1; i <= num / 2; i++) //兩個大於num/2的整數之和肯定大於num,故只需迴圈到num/2 { for (int k = 1;; k++) //k從1開始,不是從i開始 { sum = (k + 1) * (2 * i + k) / 2; if (sum > num) break; if (sum == num) { cout << num << "="; for (int j = 0; j < k; j++) cout << i + j << "+"; //輸出i+j cout << i + k << endl; } } } } return 0; }