美文网首页
1045 快速排序

1045 快速排序

作者: 初见还是重逢 | 来源:发表于2019-03-29 13:21 被阅读0次

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?

例如给定 N = 5, 排列是1、3、2、4、5。则:

  • 1 的左边没有元素,右边的元素都比它大,所以它可能是主元;
  • 尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元;
  • 尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元;
  • 类似原因,4 和 5 都可能是主元。

因此,有 3 个元素可能是主元。

输入格式:

输入在第 1 行中给出一个正整数 N(≤10^5); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 10^9。

输出格式:

在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

5
1 3 2 4 5

输出样例:

3
1 4 5

思路:

本题难度稍大,一开始使用暴力循环方法,果然只能通过三个测试用例。

后来需要观察主元的特性:
如果一个元素是主元,首先必须满足:
(1)该元素的位置是正常排序的位置
(2)该元素前的最大元素必须比该元素小。

例如数列:1 3 2 4 5
主元1 4 5的位置与正常排序时1 2 3 4 5的位置是相同的,其次,每一个主元的前面都没有比他大的元素

例如数列: 5 4 3 1 2
数字3虽然与正常排序的位置相同,但是其前面有比他大的元素,因此3不是主元

知道这个规律以后就好处理了:

关键的判断循环如下:

for (int i = 0; i < N; i++)
//要满足为主元,首先需要该元素的位置为排序后的位置
//其次,该元素前的最大元素必须比这个元素小
{
    max = max > store[i] ? max : store[i];//随时存储最大元素
    if (store[i] != tep[i])tep[i] = 0;//如果位置不对,将该元素设为0
    if (max > store[i])tep[i] = 0;//如果前面最大元素比该元素大,将该元素设置为0
    if (tep[i] != 0)result.push_back(tep[i]);//如果该元素没有设为0,证明其是主元,存在result中
}
//其中tep数组是排序后的数组,store是排序前的数组

注意本题还有一个测试点,是如果没有主元需要先输出0,然后输出一个空行。

代码:

快速排序

//1045 快速排序
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main()
{
    int N;
    cin >> N;//输入元素个数
    int temp, max = 0;//temp用于临时存储数据,max用于存放前面为止的最大数
    vector<int> store, tep, result;
    for (int i = 0; i < N; i++)//将所有元素存在store中
    {
        cin >> temp;
        store.push_back(temp);
    }
    tep = store;
    sort(tep.begin(), tep.end());//对原数组进行排序

    for (int i = 0; i < N; i++)
    //要满足为主元,首先需要该元素的位置为排序后的位置
    //其次,该元素前的最大元素必须比这个元素小
    {
        max = max > store[i] ? max : store[i];//随时存储最大元素
        if (store[i] != tep[i])tep[i] = 0;//如果位置不对,将该元素设为0
        if (max > store[i])tep[i] = 0;//如果前面最大元素比该元素大,将该元素设置为0
        if (tep[i] != 0)result.push_back(tep[i]);//如果该元素没有设为0,证明其是主元,存在result中
    }
    if (result.size() == 0)//如果没有主元,输出0,然后在输出一个空行,这是第三个测试点
    {
        cout << 0 << endl;
        cout << endl;
        return 0;
    }
    else
    {
        cout << result.size() << endl;
        for (unsigned int i = 0; i < result.size() - 1; i++)
        {
            cout << result[i] << ' ';
        }
        cout << result[result.size() - 1] << endl;
    }
    return 0;
}

相关文章

  • PAT-B 1045 快速排序(C语言)

    题目 链接:PAT (Basic Level) Practice 1045 快速排序 著名的快速排序算法里有一个经...

  • 1045 快速排序

    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它...

  • (原创,步进分析,24ms)PAT乙级1045 快速排序

    题目 1045 快速排序 (25 分)著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为...

  • PAT1045快速排序

    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它...

  • 1045 快速排序 (25 分)

  • 1045 快速排序(25)(25 分)

    著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它...

  • PAT 1045 快速排序 (25 分)

  • A1045 快速排序 (25分)

    /*题意:1、找主元,就是左边比他小,右边比它都打就是主元了 解题:1、答案说思路一样,怎么个一样法。我需要判断每...

  • PTA 1045 快速排序 (25 分)

    题目 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素...

  • PAT (Basic Level):1045 快速排序(25)

    题目信息 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的...

网友评论

      本文标题:1045 快速排序

      本文链接:https://www.haomeiwen.com/subject/enrlbqtx.html