适合初步练习PAT乙级——(1045) 快速排序

适合初步练习PAT乙级——(1045) 快速排序

著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?
例如给定 N=5N = 5N=5, 排列是1、3、2、4、5。则:
1 的左边没有元素,右边的元素都比它大,所以它可能是主元;
尽管 3 的左边元素都比它小,但其右边的 2 比它小,所以它不能是主元;
尽管 2 的右边元素都比它大,但其左边的 3 比它大,所以它不能是主元;
类似原因,4 和 5 都可能是主元。
因此,有 3 个元素可能是主元。
输入格式:
输入在第 1 行中给出一个正整数 N(≤10
​5​​); 第 2 行是空格分隔的 N 个不同的正整数,每个数不超过 10​9​​。
输出格式:
在第 1 行中输出有可能是主元的元素个数;在第 2 行中按递增顺序输出这些元素,其间以 1 个空格分隔,行首尾不得有多余空格。
输入样例:
5
1 3 2 4 5

输出样例:
3
1 4 5

#include<iostream>
#include<algorithm>

int a[100000], b[100000], v[100000];
using namespace std;
int main() {
	int n, max = 0, cnt = 0;
	cin >> n;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		b[i] = a[i];
	}
	sort(a, a + n);
	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 != 0)printf(" ");
		printf("%d", v[i]);
	}
	printf("\n");//l看别人的,这么要加换行,这里怪怪的
	return 0;
}

思路:快速排序的特点是主元的位置不变,即主元的位置就在排序的最终位置上。对原序列sort排序,逐个比较,当当前元素没有变化并且它左边的所有值的最大值都比它小的时候就是主元。用max来存储a[i]左边的最大值。

方法2:设置数组leftmax存这个数左边的最大值,leftmax[0]=0;设置rightmin存这个数右边的最小值,rightmin[n]存一个较大的数1000000000.
只要这个数比左边最大的值还要大,比右边最小的值还要小,那么这个数就是主元。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int a[100010];
int letfmax[100010];//左边最小
int rightmin[100010];//右边最大
int main() {	
	int n;
	cin >> n;	
	for (int i = 0; i < n; i++)//输入
		cin >> a[i];
	letfmax[0] = 0;
	for (int i = 1; i < n; i++) {
		letfmax[i] = max(letfmax[i-1], a[i-1]);			
	}
	rightmin[n - 1] = 1000000000;
	for (int i = n-2; i>=0; i--) {
		rightmin[i] = min(rightmin[i+1], a[i+1]);		
	}
	int count = 0;
	vector<int>ans;
	for (int i = 0; i < n; i++) {
		if (a[i] > letfmax[i] && a[i] < rightmin[i]) {
			count++;
			ans.push_back(a[i]);
		}
	}
	sort(ans.begin(), ans.end());
	cout << count << endl;
	for (int i = 0; i < ans.size(); i++) {
		if (i != 0)printf(" ");
		cout<< ans[i];
	}
    cout<<endl;
	return 0;




}
### 关于 PAT 乙级 C语言 题目1045 的解题思路 对于 PAT 乙级题目编号为 1045 的问题,虽然未提供具体描述,但可以推测其可能涉及数组操作、字符串处理或其他基础算法设计。以下是基于常见 PAT 乙级题型的通用解决方案。 #### 输入与输出分析 假设该题目要求输入一组数据并对其进行某种计算或转换,则需注意以下几点: - **输入格式**:通常会指定多组测试用例或多行输入,每行包含若干数值或字符。 - **输出格式**:严格按照题目要求定义输出形式,例如保留几位小数、按特定顺序排列等。 针对此类型的题目,推荐采用标准库函数 `scanf` 或者更灵活的方式如 `fgets` 结合手动解析来读输入[^2]。 #### 示例代码实现 下面展示一段用于解决假想中的 PAT B1045 类似需求的程序框架: ```c #include <stdio.h> #include <string.h> int main(){ int n; scanf("%d",&n); char original[81], typed[81]; while(n--){ scanf("%s %s",original,typed); // 初始化记录损坏键集合 int brokenKeys[128]={0}; for(int i=0;i<strlen(original);i++){ if(original[i]!=typed[i]){ brokenKeys[toupper(original[i])]=1; } } // 打印唯一损坏按键 int firstPrinted = 0; for(char c='A';c<='Z';c++) { if(brokenKeys[c]){ if(firstPrinted){ putchar(' '); } printf("%c",c); firstPrinted = 1; } } puts(""); } } ``` 上述代码片段展示了如何通过对比两段文本找出差异之处,并标记哪些键盘按键可能出现故障的情况[^1]。当然这只是一个例子,实际应用时应依据确切的任务说明调整逻辑细节。 #### 性能优化建议 当面对大数据量运算场景时(比如 N 达到十万级别),务必考虑时间复杂度的影响因素。如果单纯依靠嵌套循环解决问题可能会遭遇性能瓶颈,在这种情况下可尝试引入二分查找法或者其他高效的数据结构辅助完成任务[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值