PAT 乙级 1045.快速排序 C++/Java
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?
例如给定 N=5, 排列是1、3、2、4、5。则:
- 1 的左边没有元素,右边的元素都比它大,所以它可能是主元;
- 尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元;
- 尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元;
- 类似原因,4 和 5 都可能是主元。
因此,有 3 个元素可能是主元。
输入格式:
输入在第 1 行中给出一个正整数 N(≤); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 1。
输出格式:
在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
5
1 3 2 4 5
输出样例:
3
1 4 5
思路:
在循环输入元素时,可以一边判断当前输入的元素是否是目前的最大值,不是则将标记;再逆序遍历,判断元素是否为右侧部分的最小值,不是则标记。计算出未被标记的元素个数并输出,若个数为0,还要再输出一次换行,若个数大于0,则按原顺序输出。
C++实现:
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> 4 using namespace std; 5 //1045:快速排序 6 typedef struct Point{ 7 int value; 8 bool flag; 9 }Point; 10 int main() { 11 int n; 12 cin >> n; 13 vector<Point> point; 14 Point p; 15 int max = 0, count = 0; 16 for (int i = 0; i < n; i++) { 17 p.flag = true; 18 cin >> p.value; 19 if (p.value > max) { 20 max = p.value; 21 } 22 else { 23 p.flag = false; 24 } 25 point.push_back(p); 26 } 27 int min = max + 1; 28 for (int i = n - 1; i >= 0; i--) { 29 if (point[i].value < min) { 30 min = point[i].value; 31 } 32 else { 33 point[i].flag = false; 34 } 35 if (point[i].flag) { 36 count++; 37 } 38 } 39 cout << count << endl; 40 if (count > 0) { 41 bool f = true; 42 for (int i = 0; i < n; i++) { 43 if (point[i].flag) { 44 if (!f) { 45 cout << " "; 46 } 47 cout << point[i].value; 48 f = false; 49 } 50 } 51 } 52 else{ 53 cout << endl; 54 } 55 }
Java实现: