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实现:

 

posted @ 2021-04-09 15:33  47的菠萝~  阅读(52)  评论(0编辑  收藏  举报