PAT (Basic Level) 1045 柳婼、旭神两大思路分析【测试点】样例
1045 快速排序 (25 分)
著名的快速排序算法里有一个经典的划分过程:我们通常采用某种方法取一个元素作为主元,通过交换,把比主元小的元素放到它的左边,比主元大的元素放到它的右边。 给定划分后的 N 个互不相同的正整数的排列,请问有多少个元素可能是划分前选取的主元?
例如给定 N=5N = 5N=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
这道题总的来说应该是有两个思路(根据快排原理)
1.只要主元的大于左边的所有的数,并且小于右边所有的数 (考虑非主元不移动的情况)
2.只要主元在快排中不动,并且右边没有大于它的 (考虑了非主元移动的情况)
开始聊思路了,第一种思路是我最开始想的,但是只实现了用一次循环对大于左边情,右边情况并未想出。这也是柳神和旭神的思路。
只要左边的最大值小于当前主元,并且满足此主元位置和排序后的相同或者满足右边的最小值大于此主元,即可。
第二种思路,我真正实现的思路,
数组中移动的数位置和在排序后的位置之间都不是主元因为不满足条件,所以只要让开始移动的数到最大移动的数位置规定不是主元,即可。
我用的第二种思路
先给数组快排(可参考我写博客),数组中移动的数位置和在排序后的位置之间都不是主元因为不满足条件,所以只要让开始移动的数到最大移动的数位置规定不是主元,即可。 [快排之C语言(各种数据的排序) ](https://blog.csdn.net/qq_53269459/article/details/113856208)
【测试点3、5】(可以用如下测试点检测)
1 11 3 4 10 14 5 8 6 10
1 3 4 5 6 8 10 11 14 100
输出
2
1 100
11 的位置从第 2 个排到了第 8 个,说明2 - 8之间的数都不是主元,并且在2 - 8中又有大于 11 的数 14,说明 从原数组中 14 的位置到排序后 14 的位置之间的元素都不是主元,所以右边只剩下了 100,左边只有 1
#include<stdio.h>
#include<stdlib.h>
int cmp(const void *a,const void *b) //快排
{return *(int *)a-*(int *)b;
}
int main()
{int n,a[100001],b[100001],c[100001];scanf("%d",&n);for(int i = 0;i < n;i++){scanf("%d",&a[i]);b[i] = a[i];}qsort(b,n,sizeof(b[0]),cmp); //快排int sign = 0,s = 0,flag = 0;for(int i = 0;i < n;i++){if(a[i] > b[i] && a[i] > a[sign]){sign = i;flag = 0;}if(a[sign] == b[i]) flag = 1;if(a[i] == b[i] && flag) c[s++] = a[i];}printf("%d\n",s);for(int i = 0;i < s;i++){if(i != 0) printf(" ");printf("%d",c[i]);
// if(i != s-1) printf(" ");}printf("\n"); return 0;
}
C++可参考如下代码
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{int n,i,flag1=0,flag2=0,cnt=0,j;cin>>n;int a[n],b[n],c[n];for(i=0;i<n;i++){cin>>a[i];b[i]=a[i];}sort(b,b+n);int max=0;for(i=0;i<n;i++){if(max<a[i])max=a[i];if(max==a[i]&&a[i]==b[i])c[cnt++]=b[i];}cout<<cnt<<endl;for(i=0;i<cnt;i++){cout<<c[i];if(i<cnt-1)cout<<" ";}cout<<endl;return 0;
}
柳神的分析
分析:对原序列sort排序,逐个比较,当当前元素没有变化并且它左边的所有值的最大值都比它小的时候就可以认为它一定是主元(很容易证明正确性)~
如果硬编码就直接运行超时了…后来才想到这种方法~ 一开始有一个测试点段错误,后来才想到因为输出时候v[0]是非法内存,改正后发现格式错误(好像可以说明那个第2个测试点是0个主元?…)然后加了最后一句printf("\n");才正确(难道是当没有主元的时候必须要输出空行吗…)
#include <iostream>
#include <algorithm>
#include <vector>
int a[100000], b[100000], v[100000];
using namespace std;
int main() {int n, max = 0, cnt = 0;scanf("%d", &n);for (int i = 0; i < n; i++) {scanf("%d", &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];}printf("%d\n", cnt);for(int i = 0; i < cnt; i++) {if (i != 0) printf(" ");printf("%d", v[i]);}printf("\n");//不加这句会有一个测试点没法通过。.return 0;
意思就是主元位置和排序后的位置相同,并且大于前面最大的元素,别忘记加 printf(" ");
旭神的分析
第一次写的原生代码,活生生写了三次for循环,可以简化掉,输入进来,正反各循环一次,记录i个数据左边最大值,和i右边最小值,只要 第i个数据比最大值大,最小值小就是关键元素
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main(){int n;cin>>n;vector<int>num(n);vector<int>numax(n);vector<int>numin(n);int max=-1,min=1000000009;for(int i=0;i<n;i++){cin>>num[i];if(num[i]>max)max=num[i];numax[i]=max;}for(int i=n-1;i>=0;i--){if(num[i]<min)min=num[i];numin[i]=min;}int count=0;for(int i=0;i<n;i++){if(num[i]<=numin[i]&&num[i]>=numax[i]){count++;}}cout<<count<<endl;int flag=0;int cou=count;vector<int>num3(count);for(int i=0;i<n;i++){if(num[i]<=numin[i]&&num[i]>=numax[i]){num3[count-1]=num[i];count--;//cout<<num3[count];}}sort(num3.begin(),num3.end());for(int i=0;i<cou;i++){if(flag){cout<<" ";}flag=1;cout<<num3[i];}cout<<endl;return 0;
}
就是利用多次 for 循环来记下主元左边的数和主元右边的数,然后用一层最大次数为 n 的 for 循环来实现大于左边最大值和小于右边最小值。
喜欢的小伙伴可以点赞哟!!!!
PAT (Basic Level) 1045 柳婼、旭神两大思路分析【测试点】样例相关推荐
- PAT (Basic Level) 1045 快速排序(思维)
题目链接:点击查看 题目大意:根据快速排序的定义,找出主元,主元就是在未排序之前,当前位置之前的数都比其自身小,当前位置之后的数都比其自身大 题目分析:这个题可以暴力混分..但没必要,n*n的时间复杂 ...
- pat题解java,1039 到底买不买 (20分) Java题解 PAT (Basic Level) Practice (中文)- 巧妙开大数组减少代码量...
1039 到底买不买 (20分) 原题链接:传送门 一.题目: 输入样例 1: ppRYYGrrYBR2258 YrR8RrY 输出样例 1: Yes 8 输入样例 2: ppRYYGrrYB225 ...
- PAT (Basic Level) Practise (中文)-1025. 反转链表 (25)
PAT (Basic Level) Practise (中文)-1025. 反转链表 (25) http://www.patest.cn/contests/pat-b-practise/1025 ...
- PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20)
PAT (Basic Level) Practise (中文)-1034. 有理数四则运算(20) http://www.patest.cn/contests/pat-b-practise/1034 ...
- 【题解】PAT (Basic Level) Practice (中文)
互联网行业的小白,写博客的目的是为了记录自己的学习过程.对自己学习中所犯的错误做一个总结.由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教! PAT Basic Level P ...
- PAT basic level 答案+解题思路+难点 (个人刷题记录)
PAT basic level 使用语言:C++ 仅记录一下自己刷题过程的心得体会 永远保持更新(期待更好的解法) 可能有些题没有(那就是我还没做出来,以后会更的!) 欢迎大家与我讨论交流√ 题目序列 ...
- 可优化-PAT (Basic Level) Practice Python解法 1026 程序运行时间(时间进位/四舍五入Tobe解决)
可优化-PAT (Basic Level) Practice Python解法 1026 程序运行时间(时间进位/四舍五入Tobe解决) c1, c2 = map(int,input().split( ...
- 1001 害死人不偿命的(3n+1)猜想 (15分) PAT (Basic Level) Practice (中文)C语言版
PAT (Basic Level) Practice (中文) 1001 害死人不偿命的(3n+1)猜想 (15分) 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一 ...
- 卡拉兹(Callatz)猜想,PAT(Basic Level) Practise NO.1001
PAT(Basic Level) Practise NO.1001 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半. 这样 ...
- PAT (Basic Level) Practice (中文)1095 解码PAT准考证 (25 分)
PAT (Basic Level) Practice (中文)1095 解码PAT准考证 (25 分) PAT 准考证号由 4 部分组成: 第 1 位是级别,即T代表顶级:A代表甲级:B代表乙级: 第 ...
最新文章
- 创建存储器_Microchip推出首款低功耗数模转换器,集成非易失性存储器,简化手持设备设计...
- C# 世界坐标 页面坐标 PageUnit PageScale
- Swift - 使用NSNotificationCenter发送通知,接收通知
- What Does TTY Stand for in Linux?
- web前端技巧-ES6新特性与重点知识汇总(二)
- PLS-00215:字符串长度限制在范围
- Spring事务TransactionProxyFactoryBean属性-transactionAttributes的意义
- Red Hat Linux 5.4 开启xdm远程访问
- 一起动手打造个人娱乐级linux
- Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7)【转】...
- c语言 已知某系统在通信联络中,数据结构(习题)..doc
- 监督学习 | 朴素贝叶斯之Sklearn实现
- Python实现HTTP服务器(二)返回指定的html页面
- Linux服务器的优化
- 设计模式(一)----简单工厂、工厂方法和抽象工厂区别
- apache编译出错 error: mod_deflate has been requested
- 《实战》基于情感词典的文本情感分析与LDA主题分析
- gis统计百分比_ArcGIS数据统计
- php swfupload handlers.js,PHP swfupload图片文件上传实例代码
- Pandas+随机森林数模实战日记
热门文章
- macOS 常用键盘快捷键大全
- html原生控件美化,HTML表单美化
- 学习笔记:简谈boost升压电路
- 九款好看的后台管理系统登录模板
- 计算机杀毒软件的功能,PC Hunter64(手工杀毒软件)的详细功能介绍
- Rootkit Hunter恶意程序查杀
- [ScyllaHide] 05 ScyllaHide的Hook原理
- mysql更新数据的语句怎么写_mysql更新数据库语句怎么写?mysql更新字段语句
- android so文件解密器,【Android 原创】so文件动态加解密的CrackMe
- 进销存excel_简单易操作!Excel免费进销存管理系统!不花钱的进销存管理软件...