給定乙個陣列和乙個數s,在這個陣列中找乙個區間,使得這個區間之和等於s。
例如:給定的陣列int x[14] = ;和乙個s = 15。那麼,可以找到的區間就應該有0到4, 3到5, 6到7.(注意這裡的下標從0開始)
對於這樣的題,不用任何技巧就可以跑出結果,例如下面這個方法可能是大多數人能夠想出來的:
先用乙個陣列sum[i]存放前i個元素的和,其實現用的是」遞推思想「,注意,在程式設計中」遞推「的思想用的特別多,一定要習慣這種思維方式。
然後通過兩層迴圈求解sum[0]
= x[0]
;//x為給定的原陣列
for(
int i =
1; i < n; i++
)
上面的方法當然是可行的,但是複雜度太高,有乙個演算法可以將其複雜度降為o(n)。這就是」尺取演算法「。for
(int i =
0; i < n; i++
)for
(int j = n-
1; j >=
0; j--
)
尺取法:顧名思義,像尺子一樣取一段,借用挑戰書上面的話說,尺取法通常是對陣列儲存一對下標,即所選取的區間的左右端點,然後根據實際情況不斷地推進區間左右端點以得出答案。之所以需要掌握這個技巧,是因為尺取法比直接暴力列舉區間效率高很多,尤其是資料量大的。
那麼,用」尺取法「做上面這道題思路應該是這樣的:
其實,這種方法很類似於蚯蚓的蠕動。
1)用一對腳標i, j。最開始都指向第乙個元素。
2)如果區間i到j之和比s小,就讓j往後挪一位,並把sum的值加上這個新元素。相當於蚯蚓的頭向前伸了一下。
3)如果區間i到j之和比s大,就讓sum減掉第乙個元素。相當於蚯蚓的尾巴向前縮了一下。
4)如果i到j之和剛好等於s,則輸入。
#include
#include
using namespace std;
void
findsum
(int
*a,int n,
int s)
else}}
intmain()
; cin >> m;
findsum
(x,14
, m)
;return0;
}
尺取法學習
參考資料 挑戰程式設計競賽 p146 參考部落格 介紹 尺取法 顧名思義,像尺子一樣取一段,借用挑戰書上面的話說,尺取法通常是對陣列儲存一對下標,即所選取的區間的左右端點,然後根據實際情況不斷地推進區間左右端點以得出答案。之所以需要掌握這個技巧,是因為尺取法比直接暴力列舉區間效率高很多,尤其是資料量...
尺取法學習筆記
返回的推進區間開頭和結尾,求滿足條件的最小區間的方法稱為尺取法。尺取法,顧名思義,像尺子一樣,一塊一塊的擷取。用尺取法來優化,使複雜度降為了o n 整個過程分為四步 1.初始化左右端點 2.不斷擴大右端點,直到滿足條件 3.如果第二步中無法滿足條件,則終止,否則更新結果 4.將左端點擴大1,然後回到...
尺取法學習筆記
今天老師講了提了下尺取,於是就有了這篇筆記 ps 我覺得我們老師形容得很貼切,尺取就像蟲子蠕動一樣給出乙個序列,求區間和大於或者等於s的最短區間長度.3 2 8 10 5 3 8 4 2 9i 1 2 3 4 5 6 7 8 9 10 ai 3 2 8 10 5 3 8 4 2 9 l r 計算區間...