為了找份暑期實習生的工作,今天去某公司面試。很喜歡這樣的公司,首先不問出身、不問愛好,直接給你一台電腦,幾道程式設計題目,讓你寫程式。
其中有道題目是將乙個整數分解為連續正整數之和,如15可以分解為:
15 = 1 + 2 + 3 + 4 + 5
15 = 4 + 5 + 6
15 = 7 + 8
這道題,我用最死板的方法給編出來了。輸入數n,設定起始位置i,再遍歷連續正整數的長度k,由公式計算出 sum = i + (i+1) + ... + (i+k) = (k+1) * (2*i + k) / 2,判斷與n的關係,若相等則列印出從i到i+k這(k+1)個數;若sum>n,則break;
偽碼如下:
for (i = 1; i <= n/2; i++)
for (k = 1; ; k++)
sum = (k+1) * (2*i + k) / 2;
if (sum > n)
break;
if (sum == n)
print (從i到i+k的值)
但這演算法的複雜度高呀!達到o(n2)!肯定不是最好的方法,回來我在網上找了一下這個題目,發現有很多解法,說乙個比較容易理解的吧。
我們計算從i開始連續k個數之和的計算公式如下:
sum = k * (2 * i + k - 1) / 2;
現在題目要求sum == n 的所有可能情況,上面的解法是從起始位置開始迴圈,又根據連續個數迴圈,兩重迴圈,那麼從上面的公式逆向想想,如果sum==n時,i與k直接滿足什麼關係呢?有 k * (2 * i + k - 1) = 2 * n。那麼如果用k迴圈,計算出起始位置 i = ( 2*n / k - k + 1) / 2,豈不是時間複雜度降到線性的了。如下:
for (k = 1; k <= n/2; k++)
if (2*n % k == 0) //能被k整除
temp = 2*n / k - k + 1;
if (temp % 2 == 0) //能被2整除
i = temp / 2;
print (從i到i+k-1的值)
ok!
將整數分解為連續正整數之和
將乙個整數 n 分解為連續正整數之和,如 15 可以分解為 15 1 2 3 4 5 15 4 5 6 15 7 8 計算從 i 開始連續 k 個數之和 sum k 2 i k 1 2 當 sum n 時,有 k k 2 i 1 k 2 n 0 變形為 i 2 n k k 1 2。在 2,2 n k...
正整數分解為幾個連續自然數之和
題目 輸入乙個正整數,若該數能用幾個連續正整數之和表示,則輸出所有可能的正整數序列。乙個正整數有可能可以被表示為n n 2 個連續正整數之和,如 15 1 2 3 4 5 15 4 5 6 15 7 8 有些數可以寫成連續n 1 個自然數之和,比如14 2 3 4 5 有些不能,比如8.那麼如何判斷...
正整數分解為幾個連續自然數之和
題目 輸入乙個正整數,若該數能用幾個連續正整數之和表示,則輸出所有可能的正整數序列。乙個正整數有可能可以被表示為n n 2 個連續正整數之和,如 15 1 2 3 4 5 15 4 5 6 15 7 8 有些數可以寫成連續n 1 個自然數之和,比如14 2 3 4 5 有些不能,比如8.那麼如何判斷...