常用技巧之 尺取法 理解 例題

2021-06-22 19:32:01 字數 2010 閱讀 1396

尺取法的複雜度為 o(n) ,主要應用有關連續性的問題,基本原理就是反覆地推進區間的開頭和末尾,來求取滿足條件的最小區間,或者相似的應用。

尺取法在別的地方又被稱為滑動視窗或者蠕蟲演算法,我覺得蠕蟲演算法這個名稱用的相當恰當啊,就是一步一步地往後移動,一直找到答案,而不用遍歷回溯什麼的,也就是因為這樣,他的複雜度才這麼低。

舉例子什麼的,就直接看題目好了,搞了三個例題,看完應該會有一定的理解了吧。

nbut 1052  想**的字串

該題就是讓你求最短的,同時包含a b c 的字串的長度,資料較水,好像遍歷,dp 也可以過,這題用尺取法的話,時間是0 ms,也就是說還是很高效的。

#include#include#includeusing namespace std;

char tt[1010];

int cnt[200];

int main()

if(cnt['a'] && cnt['b'] && cnt['c'])

ans = min(sta - i + 1, ans);

cnt[tt[i]] --;

}printf("%d\n", ans);

}}

poj  3061  subsequence

該題就是給你長度為n的整列整數a[0],a[1],……a[n-1],以及整數s,求出總和不小於s的連續子串行的長度的最小值。

你只要不斷的把下標往前「 蠕動 」 就可以了,比如a[0],a[1]....a[k],然後a[1],a[2]....a[k],a [k+1] , 一直持續著,中間可能有多種滿足狀況,你要找出最短的長度即可

#include#include#include#include#includeusing namespace std;

const int inf = 0x7fffffff;

int tt[100010];

int t, n, tot;

int main()

if(sum < tot)

break;

ans = min(ans, endd - sta);

sum -= tt[sta ++];

}if(ans == inf)

printf("0\n");

else

printf("%d\n",ans);}}

return 0;

}

該題感覺稍微複雜一點,但是和第一題幾乎一模一樣,要注意的是,但m 為3 的時候,就不能考慮d, e , f, 什麼的,這題題意我看錯了三次,還好最後還是一a,直接上**了(該解法還是rank 的第一   其它的解法好像也有0ms 的,  大神請一定分享一下啊 ,在下感激不盡)  好吧,其實你會發現judge 的兩個函式一樣的,cnt 和nut的重複,自己再改一下好了,這是比賽的**知己貼上去了- 。 -

#include#include#include#include#includeusing namespace std;

const int n = 100010;

char tt[1010];

int cnt[1110]; // 看是否出現過該字元

int nut[1110];

int t, a, b;

int num;

int judge()

return 0;

}int judge1()

return 0;

}int main()

if(judge() == 0)

ans = min(sta - i + 1, ans);

cnt[tt[i]] --;

// printf("%d %d %d\n",sta, i, ans);

}if(judge1() == 0 || ans < a)

printf("%d\n",ans);

else

printf("i am so fat!\n");}}

return 0;

}

常用的解題技巧 尺取法

尺取法 顧名思義,像尺子一樣取一段,借用挑戰書上面的話說,尺取法通常是對陣列儲存一對下標,即所選取的區間的左右端點,然後根據實際情況不斷地推進區間左右端點以得出答案。之所以需要掌握這個技巧,是因為尺取法比直接暴力列舉區間效率高很多,尤其是資料量大的時候,所以尺取法是一種高效的列舉區間的方法,一般用於...

資料結構之常用排序演算法理解

1.選擇排序 遍歷陣列,每一次遍歷找出乙個最小值放在陣列前面,步驟如下 將currmin設為a 0 遍歷a 1 a n 1 只要a i 小於a 0 進行a 0 與a i 的交換 將currmin設為a 1 遍歷a 2 a n 1 最後乙個currmin為a n 2 比較a n 2 與a n 1 如下...

Linux常用技巧之四

41 刪除了 etc inittab 修復辦法如下!1 首先進去 linux 的rescue 的模式!2 然後使用如下的命令 rpm qf root mnt sysimage etc inittab 查出該檔案屬於哪個 rpm包!3 然後重新安裝這個 rpm包!rpm ivh force root ...