1. 快速排序c++
#include <bits/stdc++.h> using namespace std; const int N = 1000010; int q[N]; void quick_sort(int q[], int l, int r) { if (l >= r) return; // 使得l恆小於等於r int i = l - 1, j = r + 1, x = q[l + r >> 1]; // 定義雙指針和分界點 while(i < j) { do i++; while (q[i] < x); // x左邊的數字比x小 do j--; while (q[j] > x); // x右邊的數字比x大 if (i < j) swap(q[i], q[j]); } quick_sort(q, l, j); // 對x左邊和右邊的區間再進行快排,分界點是j quick_sort(q, j + 1, r); } int main() { int n; scanf("%d", &n); for (int i = 0; i < n; i ++ ) scanf("%d", &q[i]); quick_sort(q, 0, n - 1); for (int i = 0; i < n; i ++ ) printf("%d ", q[i]); return 0; }
2. 快排求第k小app
#include <bits/stdc++.h> using namespace std; int const N = 1e5 +10; int k, n; int q[N]; int quick_sort(int l, int r) { if (l >= r) return q[l]; int i = l - 1, j = r + 1, x = q[l]; while (i < j) { do i++; while (q[i] < x); do j--; while (q[j] > x); if (i < j) swap(q[i], q[j]); } if (j >= k - 1) quick_sort(l, j); // 若是j指向的位置大於等於k-1,那麼只須要對左半區間進行快排,右半區間無需操做,省去一半的時間 else quick_sort(j + 1, r); } int main() { cin >> n >> k; for (int i = 0; i < n ;++i) scanf("%d", &q[i]); int t = quick_sort(0, n - 1); cout << t; return 0; }
1. 歸併排序函數
#include <bits/stdc++.h> using namespace std; const int N = 1e6 + 10; int tmp[N], q[N]; void merge_sort(int l, int r) { if (l >= r) return ; int mid = (l + r) >> 1; int i = l, j = mid + 1, k = 0; merge_sort(l, mid), merge_sort(mid + 1, r); while (i <= mid && j <= r) { if (q[i] < q[j]) tmp[k ++] = q[i ++]; else tmp[k ++] = q[j++]; } while (i <= mid ) tmp[k ++] = q[i ++]; while (j <= r) tmp[k ++] = q[j ++]; for (int i = l, k = 0; i <= r; ++i) q[i] = tmp[k ++]; } int main() { int n; cin >> n; for (int i = 0 ; i < n ; ++i) scanf("%d", &q[i]); merge_sort(0, n - 1); for (int i = 0; i < n; ++i) cout << q[i] << " "; return 0; }
2. 歸併排序求逆序對ui
#include <bits/stdc++.h> using namespace std; int const N = 1e7 + 10; int q[N], tmp[N]; int n; double ans = 0; // 記錄答案 void merge_sort(int l, int r) { if (l >= r) return; int mid = (l + r) >> 1; merge_sort(l, mid ), merge_sort(mid + 1, r); int i = l, j = mid + 1, k = 0; while (i <= mid && j <= r) { if (q[i] <= q[j]) tmp[k ++] = q[i++]; else { ans += mid - i + 1; // 從i~mid這段的數字均爲逆序對 tmp[k++] = q[j ++]; } } while (i <= mid ) tmp[k ++] = q[i ++]; while (j <= r) tmp[k++] = q[j ++]; for (int i = l, k = 0; i <= r; ++i) q[i] = tmp[k ++ ]; } int main() { cin >> n; for (int i = 0 ; i < n; ++i) scanf("%d", &q[i]); merge_sort(0, n - 1); printf("%.0f", ans); return 0; }
1. 直接在結構體內重載spa
#include <bits/stdc++.h> using namespace std; struct Range // 按l從小到大排序(return l < R.l;);按l從大到小排序(return l > R.l;) 這句始終不變:(bool operator< (const Range &R)const) { int l, r; bool operator< (const Range &R)const { return l < R.l; } }range[100]; int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { int l, r; cin >> l >> r; } sort(range, range + n, cmp); return 0; }
2. 定義cmp函數指針
#include <bits/stdc++.h> using namespace std; struct Range { int l, r; }range[100]; bool cmp(struct Range x, struct Range y) { return x.l < y.l; // 按l從小到大排序(x.l < y.l),按l從大到小排序(x.l > y.l) } int main() { int n; cin >> n; for (int i = 0; i < n; ++i) { int l, r; cin >> l >> r; } sort(range, range + n, cmp); return 0; }
sort(a, a + cnt); cnt = unique(a, a + cnt) - a; // cnt爲去重後的序列長度
思想
把一個大的區間S映射到一個小的區間s,映射的原理是:大區間有不少的值沒有使用,能夠選擇把這些值給忽略code
板子
1. 離線離散化排序
void read_discrete() { cin >> n >> m; for (int i = 1; i <= m; ++i) { char str[5]; scanf("%d%d%s", &query[i].l, &query[i].r, str); query[i].ans = (str[0] == 'o'? 1: 0); a[++t] = query[i].l - 1; a[++t] = query[i].r; } sort(a + 1, a + 1 + t); n = unique(a + 1, a + 1 + t) - a - 1; } // main read_discrete(); for (int i = 1 ; i <= m; ++i) { int x = lower_bound(a + 1, a + n + 1, query[i].l - 1) - a; int y = lower_bound(a + 1, a + n + 1, query[i].r) - a; }
2. 在線離散化ci
#include <unordered_map> unordered_map<int, int> S; int cnt; int mapping(int x) { if (!S.count(x)) S[x] = ++cnt; return S[x]; } // main for (int i = 0; i < m; ++i) { cin >> a >> b; a = mapping(a), b = mapping(b); }