1045 快速排序 (25 分)
输入格式:
输入在第 1 行中给出一个正整数 N(≤105); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 109。
输出格式:
在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
5
1 3 2 4 5
输出样例:
3
1 4 5
解:硬编码直接运行超时 。。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <sstream>
#include <cmath>
#include <algorithm>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <map>
using namespace std;
int flag1[100005];
int a[100005];
int main() {
int n;
cin >> n;
for (int i = 0; i<n; i++) {
scanf("%d", &a[i]);
flag1[i] = 1;
}
for (int i = 0; i<n; i++) {
for (int j = 0; j<i; j++) {
if (a[j]>a[i]) {
flag1[i] = 0;
break;
}
}
}
for (int i = 0; i<n; i++) {
for (int k = i + 1; k<n; k++) {
if (a[k]<a[i]) {
flag1[i] = 0;
break;
}
}
}
int cnt = 0;
for (int i = 0; i<n; i++) {
if (flag1[i] == 1) {
cnt++;
}
}
cout << cnt << endl;
for (int i = 0; i<n; i++) {
if (flag1[i] == 1) {
printf("%d", a[i]);
if (i != n - 1) printf(" ");
}
}
return 0;
}
借鉴大佬代码后:
#include <iostream>
#include <algorithm>
#include <vector>
int v[100005];
using namespace std;
int main(){
int n,max=0,cnt=0;
scanf("%d",&n);
vector<int> a(n), b(n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(a.begin(),a.end());
for(int i=0;i<n;i++){
//主元的位置与排序后该元素的位置相同,并且后面的必须大于前面的最大值
if(a[i]==b[i] && b[i]>max)
v[cnt++]=b[i];
if(b[i]>max)
max=b[i];
}
cout<<cnt<<endl;
for(int i=0;i<cnt;i++){
if(i) cout<<" ";
cout<<v[i];
}
cout<<endl;
return 0;
}
分析:对原序列sort排序,逐个⽐较,当当前元素没有变化并且它左边的所有值的最⼤值都⽐它⼩的 时候就可以认为它⼀定是主元(很容易证明正确性的,毕竟⽆论如何当前这个数要满⾜左边都⽐他⼤ 右边都⽐他⼩,那它的排名【当前数在序列中处在第⼏个】⼀定不会变)~ 如果硬编码就直接运⾏超时了…后来才想到这种⽅法~ ⼀开始有⼀个测试点段错误,后来才想到因为输出时候v[0]是⾮法内存,改正后发现格式错误(好像可 以说明那个第2个测试点是0个主元?…)然后 加了最后⼀句printf(“\n”);才正确(难道是当没有主元的时候必须要输出空⾏吗…
笔记:快速排序中
1:主元的位置与排序后该元素的位置相同,但反之则不一定,例如3,2,1排序完后,2依旧在中间,但2不是主元;
2:加上1,后面的元素要大于前面元素的最大值,则就是主元了。