题目分析
题目分析
找到可以作为快排划分点的元素个数;
解题思路
找到递推关系
1、正向遍历数列,记录每个元素左侧的最大值left_max[i]
;
2、反向遍历,记录每个元素右侧的最小值right_min[i]
;
3、再遍历一遍,看每个元素是否left_max[i] < seq[i] < right_min[i]
;
注意点:
1、若主元个数为0,则第二行仍需输出一个空行
2、数列中的数会很大,所以边界也要设置的足够大
AC程序(C++)
/**********************************
*@ID: 3stone
*@ACM: PAT. A1101 Quick Sort
*@Time: 17/3/6
*@IDE: DEV C++ 5.9
***********************************/
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 100010;
const int INF = 0x3fffffff;
int seq[maxn];
int left_max[maxn];
int right_min[maxn];
vector<int> pivot;
/*
解题思路:
左右各扫描一遍,记录到该位时,左侧的最大值,右侧的最小值
*/
int main() {
int N;
while(scanf("%d", &N) != EOF) {
left_max[0] = 0; //左边界
right_min[N - 1] = INF; //右边界
pivot.clear();
for(int i = 0; i < N; i++) { //边输入记录每个元素左侧的最大值
scanf("%d", &seq[i]);
if(i != 0) {
left_max[i] = max(left_max[i - 1], seq[i - 1]);
}
}
for(int i = N - 2; i >= 0; i--) { //记录每个元素右侧的最小值
right_min[i] = min(right_min[i + 1], seq[i + 1]);
}
for(int i = 0; i < N; i++) {
if(left_max[i] < seq[i] && seq[i] < right_min[i]) { //元素是互异的
pivot.push_back(seq[i]);
}
}
printf("%d\n", pivot.size());
for(int i = 0; i < pivot.size(); i++) {
printf("%d", pivot[i]);
if(i < pivot.size() - 1) printf(" ");
}
printf("\n");
}
return 0;
}