1045 快速排序 (25 分)

题目链接:1045 快速排序 (25 分)

这道题目困扰我好久了。我知道自己数据结构与算法的基础知识没有掌握好。这是其中内部排序的

快速排序。

我刚开始的思路是遍历整个数组,针对每一个元素判断其是否满足主元的条件,即

当前元素大于之前元素的最大值&&当前元素小于之后元素的最小值。确定之前元素的最大值比较容易,

遍历时每次刷新最大值即可,但是之后元素的最小值缺难到了我!

参考网上大佬的想法:可以这样做,事先进行两次遍历,第一次遍历从前向后,用一个数组记录每个位置

之前的最大元素;第二次遍历从后向前,用一个数组记录每个位置之后的最小元素。

最后一次遍历,判断该元素是否满足条件并记录。

自己有这个想法,但是我逻辑太混乱了,没能实现,参考网上的如下:

代码一:

#include <bits/stdc++.h>
using namespace std;

const int N=100001;

int a[N];
int LeftMax[N],RightMin[N];
int ans[N];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%d",a+i);
    LeftMax[0]=a[0];RightMin[n-1]=a[n-1];
    //LeftMax[i]记录下标i之前的最大元素的值。LeftMax[0]默认为a[0],不冲突
    for(int i=1;i<n;i++)
        LeftMax[i]=max(LeftMax[i-1],a[i-1]);
    for(int i=n-2;i>=0;i--)
        RightMin[i]=min(RightMin[i+1],a[i+1]);
    int count=0;
    for(int i=0;i<n;i++)
    {
        if(a[i]>=LeftMax[i]&&a[i]<=RightMin[i])
            ans[count++]=a[i];
    }
    printf("%d\n",count);
    for(int i=0;i<count;i++)
    {
        printf("%d",ans[i]);
        if(i!=count-1)
            printf(" ");
    }
    printf("\n");
    return 0;
} 

之后又参考网上的其它解法,

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int a[100001];
 5 int b[100001];
 6 vector<int>ans;
 7 int main()
 8 {
 9     int n;
10     cin>>n;
11     for(int i=0;i<n;i++)
12     {
13         scanf("%d",&a[i]);
14         b[i]=a[i];
15     }
16     sort(b,b+n);
17     int curmax=0;
18     for(int i=0;i<n;i++)
19     {
20         if(a[i]==b[i]&&a[i]>curmax)
21             ans.push_back(a[i]);
22         if(a[i]>curmax)
23             curmax=a[i];
24     }
25     sort(ans.begin(),ans.begin()+ans.size());
26     cout<<ans.size()<<endl;
27     for(int i=0;i<ans.size();i++)
28     {
29         cout<<ans[i];
30         if(i!=ans.size()-1)
31             cout<<" ";
32      }
33     cout<<endl;
34     return 0;
35 } 

原文地址:https://www.cnblogs.com/ManOK/p/10306695.html

时间: 2024-10-08 16:59:33

1045 快速排序 (25 分)的相关文章

PAT Basic 1045 快速排序 (25 分)

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定 $N = 5$, 排列是1.3.2.4.5.则: 1 的左边没有元素,右边的元素都比它大,所以它可能是主元: 尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元: 尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主

1045. 快速排序(25)

1045. 快速排序(25) 著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定N = 5, 排列是1.3.2.4.5.则: 1的左边没有元素,右边的元素都比它大,所以它可能是主元: 尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元: 尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是

PAT 1045. 快速排序(25)

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元? 例如给定N = 5, 排列是1.3.2.4.5.则: 1的左边没有元素,右边的元素都比它大,所以它可能是主元: 尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元: 尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是主元: 类似原因,4和5都可能

PAT 乙级 1045. 快速排序(25)

树状数组+离散化.把所有数字离散化到1--n,设离散化之后的数组为m[a[i]],对于主元,只有m[a[i]]==i的m[a[i]]才可能.然后要算m[a[i]]之前比m[a[i]]小的个数是否为m[a[i]]-1,如果是的,那么就是主元,利用树状数组可以在log(n)效率内运算前缀和或者更新单点.坑点就是如果答案是0,那么要输出0和一个空行. #include<cstdio> #include<cstring> #include<cmath> #include<

4-9 二叉树的遍历 (25分)

4-9 二叉树的遍历   (25分) 输出样例(对于图中给出的树): Inorder: D B E F A G H C I Preorder: A B D F E C G H I Postorder: D E F B H G I C A Levelorder: A B C D F G I E H 代码:(都是遍历的算法) 1 // 4-9 二叉树的遍历 2 // 3 // Created by Haoyu Guo on 04/02/2017. 4 // Copyright ? 2017 Haoy

5-24 树种统计 (25分)

5-24 树种统计   (25分) 随着卫星成像技术的应用,自然资源研究机构可以识别每一棵树的种类.请编写程序帮助研究人员统计每种树的数量,计算每种树占总数的百分比. 输入格式: 输入首先给出正整数N(\le 10^5≤10?5??),随后N行,每行给出卫星观测到的一棵树的种类名称.种类名称由不超过30个英文字母和空格组成(大小写不区分). 输出格式: 按字典序递增输出各种树的种类名称及其所占总数的百分比,其间以空格分隔,保留小数点后4位. 输入样例: 29 Red Alder Ash Aspe

5-20 表达式转换 (25分)

5-20 表达式转换 (25分) 算术表达式有前缀表示法.中缀表示法和后缀表示法等形式.日常使用的算术表达式是采用中缀表示法,即二元运算符位于两个运算数中间.请设计程序将中缀表达式转换为后缀表达式. 输入格式: 输入在一行中给出不含空格的中缀表达式,可包含+.-.*.\以及左右括号( ),表达式不超过20个字符. 输出格式: 在一行中输出转换后的后缀表达式,要求不同对象(运算数.运算符号)之间以空格分隔,但结尾不得有多余空格. 输入样例: 2+3*(7-4)+8/4 输出样例: 2 3 7 4

5-17 汉诺塔的非递归实现 (25分)

5-17 汉诺塔的非递归实现   (25分) 借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为"a")通过借助柱(标记为"b")移动到目标柱(标记为"c"),并保证每个移动符合汉诺塔问题的要求. 输入格式: 输入为一个正整数N,即起始柱上的盘数. 输出格式: 每个操作(移动)占一行,按柱1 -> 柱2的格式输出. 输入样例: 3 输出样例: a -> c a -> b c -&g

5-3 树的同构 (25分)

5-3 树的同构   (25分) 给定两棵树T1和T2.如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是"同构"的.例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A.B.G的左右孩子互换后,就得到另外一棵树.而图2就不是同构的. 图1 图2 现给定两棵树,请你判断它们是否是同构的. 输入格式: 输入给出2棵二叉树树的信息.对于每棵树,首先在一行中给出一个非负整数NN (\le 10≤10),即该树的结点数(此时假设结点从0到N-1N?1编号):随后NN行,第i