排序、去重與離散化

排序、去重與離散化

1. 排序

1.1 快速排序

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.2 歸併排序

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.3 自定義排序寫法

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;
}

2. 去重

sort(a, a + cnt);
    cnt = unique(a, a + cnt) - a;  // cnt爲去重後的序列長度

3. 離散化

思想
    把一個大的區間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);
}
相關文章
相關標籤/搜索