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;
}
有帮助的话可以点个赞,我会很开心的~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?