P1045 快速排序
P1045 快速排序
转跳点:
1045 快速排序 (25分)
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 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
1 4 5
这道题实现起来并不难,但是吧,时间复杂度的控制是一个很麻烦的事情。
我AC的思路如下:
对原序列sort排序,逐个比较,若当前元素没有变化并且它左边的所有值的最大值都比它小的时候就可以认为它一定是主元(很容易证明正确性的,毕竟无论如何当前这个数要满足左边都比他小右边都比他大,那它的排名一定不会变)~
说白了就是找区间最大值(只不过我这里利用了之前比较的结果),如果前面的都比当前元素小那么,它的比左边都大就成立了,如果他还比右边小那么,肯定是主元。如果 右边比区间最大值小,那么记下来区间最大值,从从这个值开往后,如此往复就得出答案啦
AC代码:
#include <stdio.h>
#include <stdlib.h> int cmp(const void *a, const void *b) { return *(int *)a > *(int *)b; } int main()
{
int n, max = 0, count = 0;
scanf("%d", &n);
int a[n], b[n], cn[n]; for (int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
cn[i] = a[i];
} qsort(cn, n, sizeof(cn[0]), cmp); for (int i = 0; i < n; i++)
{
if (a[i] > max)
{ //右边有比ta大的直接替换
max = a[i];
}
if (max == a[i] && a[i] == cn[i])
{ //左边所有值的最大值为当前元素 && 如果排序前后位置没变
b[count++] = a[i];
}
} printf("%d\n", count); if (0 == count)
{
printf("\n");//这是个坑,么得主元输出空行
return 0;
} for (int i = 0; i < count; i++)
{
printf("%d%s", b[i], i == count - 1 ? "" : " ");
} return 0;
}
我又看了一些博客,说什么快速排序前后主元位置不变……人家快排都不稳定好不好……
例如序列3 2 1 4 5,排序后,是1 2 3 4 5,通过比较主元为2 4 5,一看就是错的lo,2肯定不是主元啦~
快速排序重新排序后,与原序列比较,位置不变的元素,只是有可能是主元,也会混入非主元元素的啦~
所以:
主元一定包含在了排序后位置不变的元素中,但位置不变的元素不一定是主元。
PTA不易,诸君共勉!
P1045 快速排序的更多相关文章
- [C#][算法] 用菜鸟的思维学习算法 -- 马桶排序、冒泡排序和快速排序
用菜鸟的思维学习算法 -- 马桶排序.冒泡排序和快速排序 [博主]反骨仔 [来源]http://www.cnblogs.com/liqingwen/p/4994261.html 目录 马桶排序(令人 ...
- 算法与数据结构(十六) 快速排序(Swift 3.0版)
上篇博客我们主要聊了比较高效的归并排序算法,本篇博客我们就来介绍另一种高效的排序算法:快速排序.快速排序的思想与归并排序类似,都是采用分而治之的方式进行排序的.快速排序的思想主要是取出无序序列中第一个 ...
- [算法]——快速排序(Quick Sort)
顾名思义,快速排序(quick sort)速度十分快,时间复杂度为O(nlogn).虽然从此角度讲,也有很多排序算法如归并排序.堆排序甚至希尔排序等,都能达到如此快速,但是快速排序使用更加广泛,以至于 ...
- 排序算法----调用库函数qsort进行快速排序
功 能: 快速排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const ...
- Html5 快速排序演示
快速排序(Quicksort)是对冒泡排序的一种改进.快速排序由C. A. R. Hoare在1962年提出. 它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另 ...
- Java 快速排序两种实现
快速排序,只要学习过编程的人肯定都听说过这个名词,但是有时候写的时候还真蒙住了,网上搜罗了下以及查阅了"introduction to algorithm",暂时找到两种实现快排的 ...
- java基础算法之快速排序
快速排序(Quicksort)是对冒泡排序的一种改进.在大学学过之后现在基本忘了,最近在好多地方都看到说快速排序在面试会问到,于是自己也准备重新拾起以前忘记的东西来,慢慢的积累自己的基础知识.figh ...
- PAT 1045. 快速排序(25)
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边. 给定划分后的N个互不相同的正整数的排列,请问有多 ...
- 快速排序中的partition函数的枢纽元选择,代码细节,以及其标准实现
很多笔试面试都喜欢考察快排,叫你手写一个也不是啥事.我很早之前就学了这个,对快速排序的过程是很清楚的.但是最近自己尝试手写,发现之前对算法的细节把握不够精准,很多地方甚至只是大脑中的一个映像,而没有理 ...
随机推荐
- 三、linux基础-常用命令man_cd_|_find_ln_>_history
3通用命令3.1 man命令man pwd 来查看该命令的全部帮助手册备注:命令最终是在内核中执行的,但是内核并无法直接识别,所以先通过shell执行,然后再交给内核执行3.2 cd 命令c ...
- get方法和load方法的区别
get方法的特点 get方法采用的是立即检索策略(查询):执行到这行的时候,马上发送SQL查询 get方法查询后返回的是真实对象的本身 load方法的特点 load方法采用的是延 ...
- Redis的C++与JavaScript访问操作
上篇简单介绍了Redis及其安装部署,这篇记录一下如何用C++语言和JavaScript语言访问操作Redis 1. Redis的接口访问方式(通用接口或者语言接口) 很多语言都包含Redis支持,R ...
- 日常使用SqlServer的笔记
表操作 查表大小 sp_spaceused 表名 修改表名 ALTER TABLE table RENAME TO NEW_TABLE_NAME; 修改列名 不支持 ALTER TABLE table ...
- Linux之系统优化配置
Linux系统优化配置 更新国内镜像源 国内速度快的常用更新源如下: http://mirrors.sohu.com http://mirrors.163.com [root@greymous ...
- BUAA软工第一次作业-热身
第一次作业-热身 项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) (北京航空航天大学 - 计算机学院) 这个作业的要求在哪里 第一次作业-热身作业(阅读) 我在这个课程 ...
- java并发初探ReentrantWriteReadLock
java并发初探ReentrantWriteReadLock ReenWriteReadLock类的优秀博客 ReentrantReadWriteLock读写锁详解 Java多线程系列--" ...
- canvas的其他应用
画布的基础知识 专门研究画布的大佬 手动实现echar的大佬 echar官方 画布之水印 ctx.font = "bold 20px Arial"; ctx.lineWidth = ...
- express写的接口在疯狂刷新几十次后,服务器挂掉
用到的命令行: show status like 'Threads%'; show variables like '%max_connections%'; show global status lik ...
- 防止SQL注入的登录页面
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/T ...