天天看点

PAT乙级1045

1045. 快速排序(25)

时间限制

200 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

CAO, Peng

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的N个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?

例如给定N = 5, 排列是1、3、2、4、5。则:

  • 1的左边没有元素,右边的元素都比它大,所以它可能是主元;
  • 尽管3的左边元素都比它小,但是它右边的2它小,所以它不能是主元;
  • 尽管2的右边元素都比它大,但其左边的3比它大,所以它不能是主元;

    类似原因,4和5都可能是主元。

    因此,有3个元素可能是主元。

    输入格式:

    输入在第1行中给出一个正整数N(<= 105); 第2行是空格分隔的N个不同的正整数,每个数不超过109。

    输出格式:

    在第1行中输出有可能是主元的元素个数;在第2行中按递增顺序输出这些元素,其间以1个空格分隔,行末不得有多余空格。

  • 输入样例:

      5

      1 3 2 4 5

  • 输出样例:

      3

#include<iostream>
#include<vector>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
  int N;
  cin >> N;
  vector<int> v;
  int temp;
  while (N--)
  {
    cin >> temp;
    v.push_back(temp);
  }
  vector<int> min, max;//保存每个数在它之前的这一段中的最大数和在它之后的这一段中的最小数
  int Min = 1000000001, Max = 0;
  for (int i = 0; i < v.size(); i++)
  {
    if (Min > v[v.size()-1-i])
    {
      Min = v[v.size()-1-i];
      
    }
    min.push_back(Min);
    if (Max <v[i])
    {
      Max = v[i];
      
    }
    max.push_back(Max);
  }
  reverse(min.begin(), min.end());//因为我用的vector,需要逆转下,才能与数字相对应
  vector<int> vv;
  for (int i = 0; i < v.size(); i++)
  {
    if (min[i] == max[i])
    {
      vv.push_back(v[i]);
    }
  }

  cout << vv.size() << endl;
  sort(vv.begin(), vv.end());
  if (!vv.size())
    cout << endl;//这个地方是个坑,当0个元素能够成为主元时,还得输出空行,题目没说清
  else
  for (int i = 0; i < vv.size(); i++)
  {
    cout << vv[i];
    if (i != vv.size() - 1)
      cout << " ";
    else
      cout << endl;
  }
  
  return 0;
}      

继续阅读