☆1045 快速排序 (25 分)

1045 快速排序 (25 分)

输入格式:

输入在第 1 行中给出一个正整数 N(≤10​5​​); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 10​9​​。

输出格式:

在第 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,后面的元素要大于前面元素的最大值,则就是主元了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值