1045 快速排序 (25 分)
题目链接
算法分析
数据范围是
所以我们初步判断,O(N^2)的算法肯定是过不去的。
由于题目中一直在疯狂暗示当前下标元素前面的最大值与后面的最小值,所以我们就可以正反跑两次循环,解决这个问题。
第一次循环,可以在读入数据时完成,用mn【】数组记录当前下标位置及以前的元素的最大值。
第二次循环,无需再开一个数组,只要一边循环一边处理即可,我用了一个mx来记录当前元素后面出现的最小值,并在判断过程中把结果保存在一个栈里面。
测试点
我这个题卡在了测试点二,比较神奇,是因为这个题的数据里面要求0的时候再输出一行空行,所以加上一句特判就OK(大无语事件发生了属于是 )
代码实现
#include<bits/stdc++.h>
using namespace std;
#define N 100005
int a[N], mn[N], ans[N];
int t;//栈顶下标
int main(){
int n;
scanf("%d", &n);
for(int i = 1; i <= n; ++ i){
scanf("%d", a + i);
mn[i] = max(mn[i - 1], a[i]);//第一次循环的处理
}
int mx = 1e9;
for(int i = n; i >= 1; -- i){
if(mn[i - 1] < a[i] && a[i] < mx)//第二次循环的处理
ans[++ t] = a[i];//存下答案
mx = min(mx, a[i]);
}
sort(ans + 1, ans + t + 1);//排序
printf("%d\n", t);
if(!t) printf("\n");//恶心的数据点
for(int i = 1; i <= t; ++ i){
printf("%d", ans[i]);
if(i < t) printf(" ");
}
return 0;
}