1. 程式人生 > 其它 >acwing基礎演算法第一課

acwing基礎演算法第一課

基礎演算法

一、排序(分治)

  1.快排:n*logn

    1.確定分界點。

    2.調整區間,左邊小於x(可以是中間值、標記值),右邊大於x。

    3.遞迴處理左右兩段 。

      1.分為左右a[ ],b[ ]。

      2.判斷當前元素大小(正序),若q(x)<x(小於x),x放在a[ ],反之,x放b[ ].(或用指標交換,更加優美。直接交換當前兩個位置不對數)。

 

 1 void quick_sort(int q[], int l, int r)
 2 {
 3     if (l >= r) return;
 4 
 5     int i = l - 1
, j = r + 1, x = q[l + r >> 1]; 6 while (i < j) 7 { 8 do i ++ ; while (q[i] < x); 9 do j -- ; while (q[j] > x); 10 if (i < j) swap(q[i], q[j]); 11 } 12 quick_sort(q, l, j), quick_sort(q, j + 1, r); 13 } 14 15 作者:yxc 16 連結:https://www.acwing.com/blog/content/277/
17 來源:AcWing 18 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

   

  2.歸併排序:logn*n

    1.確定分界點mid=(l+r)/2。

    2.遞迴排序左右兩個區間left、right。

    3.歸併--合二為一。left和right已是有序陣列,因此,將同時便利兩個陣列,對兩個數進行比較,小的數插入答案陣列ans,並繼續尋找。

 1 void merge_sort(int q[], int l, int r)
 2 {
 3     if (l >= r) return;
 4 
 5     int mid = l + r >> 1
; 6 merge_sort(q, l, mid); 7 merge_sort(q, mid + 1, r); 8 9 int k = 0, i = l, j = mid + 1; 10 while (i <= mid && j <= r) 11 if (q[i] <= q[j]) tmp[k ++ ] = q[i ++ ]; 12 else tmp[k ++ ] = q[j ++ ]; 13 14 while (i <= mid) tmp[k ++ ] = q[i ++ ]; 15 while (j <= r) tmp[k ++ ] = q[j ++ ]; 16 17 for (i = l, j = 0; i <= r; i ++, j ++ ) q[i] = tmp[j]; 18 } 19 20 作者:yxc 21 連結:https://www.acwing.com/blog/content/277/ 22 來源:AcWing 23 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

 

二、二分

  1.整數二分:本質:邊界

    1.mid=(l+r+1)/2,if(check(mid)),找右邊,反之找左邊。更新左邊界或右邊界,更新mid。

    

 1 bool check(int x) {/* ... */} // 檢查x是否滿足某種性質
 2 
 3 // 區間[l, r]被劃分成[l, mid]和[mid + 1, r]時使用:
 4 int bsearch_1(int l, int r)
 5 {
 6     while (l < r)
 7     {
 8         int mid = l + r >> 1;
 9         if (check(mid)) r = mid;    // check()判斷mid是否滿足性質
10         else l = mid + 1;
11     }
12     return l;
13 }
14 // 區間[l, r]被劃分成[l, mid - 1]和[mid, r]時使用:
15 int bsearch_2(int l, int r)
16 {
17     while (l < r)
18     {
19         int mid = l + r + 1 >> 1;
20         if (check(mid)) l = mid;
21         else r = mid - 1;
22     }
23     return l;
24 }
25 
26 作者:yxc
27 連結:https://www.acwing.com/blog/content/277/
28 來源:AcWing
29 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

  2.浮點數二分:

    1.mid=(l+r)/2,if(check(mid)),找右邊,反之找左邊。更新左邊界或右邊界,更新mid。(對邊界點的處理更加簡單)。

 1 bool check(double x) {/* ... */} // 檢查x是否滿足某種性質
 2 
 3 double bsearch_3(double l, double r)
 4 {
 5     const double eps = 1e-6;   // eps 表示精度,取決於題目對精度的要求
 6     while (r - l > eps)
 7     {
 8         double mid = (l + r) / 2;
 9         if (check(mid)) r = mid;
10         else l = mid;
11     }
12     return l;
13 }