pat乙级—1045快速排序

思路(参考柳诺

  • 首先要明白的一点是:在序列在排序前后,主元位置一定是不会变的;在序列在排序前后,位置不变的不一定是主元
    例如:
    原序列:1 9 4 3 5 2 10
    排序后:1 2 3 4 5 9 10
    排序前后,5位置不变,但5在原序列中并不是主元

  • 但如果排序前后,一个数位置不变,且他大于前面的所有数字,那么这个数字就是主元,利用这个结论解题

  • 下面证明:

    • 首先我们要明白:在有序序列中,对于任意数字i,所有比i小的数都放在i前面
    • 如果存在一个位置a,对于原序列和有序序列,这个位置上的数字相同,设数字为i。
    • 着眼于有序序列:因为数字i在位置a,所以原序列中比i小的数一共就a-1个
    • 着眼于原序列:如果在原序列中,i大于其前面a-1个数字,说明整个序列里比i小的数都在i左边了,那么比i大的数肯定在i的右边。因此i是主元,证毕。
    • 结合图示理解:i此时为5,由排序后的序列可知,整个序列有4个比5小的数。现在看原序列,5前面也有四个数,如果5大于前面四个数,不就意味着整个序列比5小的四个数全在他左边吗?比5小的所有数都在5左边,那比5大的肯定在右边,因此这种情况下,5是主元。
    • 下图因为5没有大于前面的四个数,所以不是主元

实现代码

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cmath>
using namespace std;
const int N=100010;
int q[N],shuzu[N],ans[N];
int main()
{
    int n,num=0,max=0;
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>q[i];
        shuzu[i]=q[i];
    }
    sort(q,q+n);
    for(int i=0;i<n;i++)
    {
        if(q[i]==shuzu[i]&&q[i]>max)//位置不变,而且大于前面的所有数,那就是主元
            ans[num++]=q[i];
        max=shuzu[i]>max?shuzu[i]:max;
    }
    cout<<num<<endl;
    for(int i=0;i<num;i++)
    {
        if(i)cout<<" ";
        cout<<ans[i];
    }
    cout<<endl;
    return 0;
}
posted @   穿过雾的阴霾  阅读(76)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示