一、题目描述
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?
例如给定 N = 5 N = 5 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
1 4 5
二、代码
//1045
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
int n;
long temp;
scanf("%d", &n);
vector<long>a;
vector<long>b;
vector<long>re;
for (int i = 0; i < n; i++)
{
scanf("%ld", &temp);
a.push_back(temp);
b.push_back(temp);
}
sort(b.begin(), b.end());
long max = 0;
for (int i = 0; i < n; i++)
{
/*if (a[i] == b[i])
if(re.size()==0 || re[re.size() - 1] != a[i])
re.push_back(a[i]);
测试点2 3 5 错误,如果左右并不符合,但碰巧位置相同是不行的
*/
if (a[i] == b[i] && a[i] > max)
re.push_back(a[i]);
if (a[i] > max)
max = a[i];
}
cout << re.size() << endl;
if (re.size() != 0)
printf("%ld", *re.begin());
if(re.size() > 1 )
for (auto it = ++re.begin(); it != re.end(); it++)
{
printf(" %ld", *it);
}
cout << endl;
return 0;
}
三、测试点错误原因及解释
- 关于超时问题:
一开始我的做法时,进行双重循环,分别比较,然而会超时。这也从通过后的样例大小可以推断出来,输入的数组其实是很大的,故如果使用的双重循环是一定会超时的。 - 关于测试点2 3 5
测试点2 的格式问题很多博主的文章都提到了,需要输出一个单独的空行
测试点2 3 5 都会考察一个问题这是我第一次没有考虑到的,就是碰巧位置相同,我发现了如果符合正确的顺序的话位置应该不变,同时考虑的是如果相同的多个数字不应该被多次计算,但忽略了左右不符合的数字数量相等的情况
比如输入:
5
5 4 3 2 1
错误输出:
1
3
所以,加入了记录左侧最大值的项,就通过了