AcWing 超快速排序

AcWing 超快速排序

Description

  • 在这个问题中,您必须分析特定的排序算法----超快速排序。

    该算法通过交换两个相邻的序列元素来处理n个不同整数的序列,直到序列按升序排序。

    对于输入序列9 1 0 5 4,超快速排序生成输出0 1 4 5 9

    您的任务是确定超快速排序需要执行多少交换操作才能对给定的输入序列进行排序。

Input

  • 输入包括一些测试用例。

    每个测试用例的第一行输入整数n,代表该用例中输入序列的长度。

    接下来n行每行输入一个整数ai,代表用例中输入序列的具体数据,第i行的数据代表序列中第i个数。当输入用例中包含的输入序列长度为0时,输入终止,该序列无需处理。

Output

  • 对于每个需要处理的输入序列,输出一个整数op,代表对给定输入序列进行排序所需的最小交换操作数,每个整数占一行。

Sample Input

5
9
1
0
5
4
3
1
2
3
0

Sample Output

6

0

Data Size

  • 0≤N<500000,
    0≤ai≤999999999

题解:

  • 交换相邻元素... ...这不就是冒泡排序的原理吗?
  • 那么,交换次数就是逆序对个数啊。yy一下很容易理解。
  • 我是用树状数组求逆序对。需要注意几点:
  1. 用树状数组一定要离散化... ...要不炸空间炸时间
  2. 如果有重复的数怎么办?没关系,有没有发现,更新的时候是+=1而不是=1
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500005
#define lowbit(x) (x & (-x))
#define LL long long
using namespace std;

LL n, cnt, ans;
LL a[N], b[N], c[N];

LL read()
{
    LL x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

LL ask(LL pos)
{
    LL r = 0;
    while(pos >= 1)
    {
        r += c[pos];
        pos -= lowbit(pos);
    }
    return r;
}

void update(LL pos, LL val)
{
    while(pos <= n)
    {
        c[pos] += val;
        pos += lowbit(pos);
    }
}

LL find(LL x) {
    return lower_bound(b + 1, b + 1 + cnt, x) - b;
}

int main()
{
    while(scanf("%lld", &n) == 1)
    {
        if(!n) break;
        ans = cnt = 0;
        memset(c, 0, sizeof(c));
        for(LL i = 1; i <= n; i++) a[i] = read(), b[++cnt] = a[i];
        sort(b + 1, b + 1 + cnt);
        cnt = unique(b + 1, b + 1 + cnt) - b - 1;
        for(LL i = 1; i <= n; i++)
        {
            LL t = find(a[i]);
            update(t, 1);
            ans += (i - ask(t));
        }
        printf("%lld\n", ans);
    }
    return 0;
}

转载于:https://www.cnblogs.com/BigYellowDog/p/11273998.html

以下是一个在 Acwing 平台上使用 C++ 实现的快速排序算法示例: ```cpp #include <iostream> using namespace std; // 交换两个元素 void swap(int& a, int& b) { int temp = a; a = b; b = temp; } // 将数组划分为两个子数组,并返回划分点的索引 int partition(int arr[], int low, int high) { int pivot = arr[low]; // 选择第一个元素作为基准值 int i = low, j = high; while (i < j) { while (i < j && arr[j] >= pivot) j--; // 从右向左找第一个小于基准值的元素 while (i < j && arr[i] <= pivot) i++; // 从左向右找第一个大于基准值的元素 if (i < j) swap(arr[i], arr[j]); // 交换找到的两个元素 } swap(arr[low], arr[i]); // 将基准值放到正确的位置上 return i; } // 快速排序递归函数 void quickSort(int arr[], int low, int high) { if (low < high) { int pi = partition(arr, low, high); // 划分点的索引 quickSort(arr, low, pi - 1); // 对划分点的左侧子数组进行排序 quickSort(arr, pi + 1, high); // 对划分点的右侧子数组进行排序 } } int main() { int n; cin >> n; // 输入数组长度 int arr[n]; for (int i = 0; i < n; i++) { cin >> arr[i]; // 输入数组元素 } quickSort(arr, 0, n - 1); for (int i = 0; i < n; i++) { cout << arr[i] << " "; // 输出排序后的数组 } cout << endl; return 0; } ``` 这段代码实现了在 Acwing 平台上进行快速排序。输入首先会读取一个整数 n,表示数组的长度。然后输入 n 个整数作为数组的元素。接下来,使用快速排序算法对这个数组进行排序,并输出排序后的结果。请注意,在 Acwing 平台上提交代码时,需要将代码放入 `int main()` 函数,且不需要包含额外的输入输出操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值