1101 Quick Sort (25 分)
There is a classical process named partition in the famous quick sort algorithm. In this process we typically choose one element as the pivot. Then the elements less than the pivot are moved to its left and those larger than the pivot to its right. Given N distinct positive integers after a run of partition, could you tell how many elements could be the selected pivot for this partition?
For example, given N=5 and the numbers 1, 3, 2, 4, and 5. We have:
- 1 could be the pivot since there is no element to its left and all the elements to its right are larger than it;
- 3 must not be the pivot since although all the elements to its left are smaller, the number 2 to its right is less than it as well;
- 2 must not be the pivot since although all the elements to its right are larger, the number 3 to its left is larger than it as well;
- and for the similar reason, 4 and 5 could also be the pivot.
Hence in total there are 3 pivot candidates.
Input Specification:
Each input file contains one test case. For each case, the first line gives a positive integer N (≤105). Then the next line contains N distinct positive integers no larger than 109. The numbers in a line are separated by spaces.
Output Specification:
For each test case, output in the first line the number of pivot candidates. Then in the next line print these candidates in increasing order. There must be exactly 1 space between two adjacent numbers, and no extra space at the end of each line.
Sample Input:
5
1 3 2 4 5
Sample Output:
3
1 4 5
分析:
题目中要找的主元要求左边的元素都比它小,右边的元素都比它大,我们可以定义一个max变量,定义左边元素中最大的元素,只要当前的元素比max大,它就可能成为主元,再从后往前遍历一遍,用min记录右边最小的元素,当前元素只要比min的小,并且满足第一次遍历的条件,就将其放入set集合中,最后输出。
我的代码:
#include<bits/stdc++.h>
using namespace std;
int a[100005];
int ans[100005];
int main(){
int n;
cin>>n;
set<int> st;
set<int> ::iterator it;
for(int i=0;i<n;i++){
cin>>a[i];
}
int max=0;
for(int i=0;i<n;i++){
if(a[i]>max){
max=a[i];
ans[i]=a[i];
}
}
int min=1000000000;
for(int i=n-1;i>=0;i--){
int tmp;
if(a[i]< min){
min=a[i];
tmp=a[i];
if(ans[i]) st.insert(tmp);
else continue;
}
}
cout<<st.size()<<endl;
for(it=st.begin();it!=st.end();it++){
if(it!=st.begin()) cout<<" ";
cout<<*it;
}
cout<<endl;
}
思考:
做这道题之前对比着先做了B1040/A1093的数PAT个数的问题,这两道题有些相似,直接暴力都会超时,都需要找到元素与元素中的联系,1040是通过A左边P和右边的T的关系来看PAT个数,这道题则是通过观察主元左右的关系。