洛谷P1923 求第K小的数 研讨关于输入输出效率的问题(scanf and cin ,printf and cout)

最简单的思想就是将这n个数从小到大排序,然后直接输出下标为K的数,不用想肯定会超时,三个测试点过了,另外两个超时。
那么我想的就是,既然全排序会超时,有没有什么方法可以不用全排序也可以拿出第K小的数呢,我想到了堆这种数据结构,我们不用使用堆排序,而是将数组建堆,不断从堆中拿出当时最小的数,当取出第K个数时,那就是我们想要的第K小的数
代码如下(因为还不会STL,于是就手写建堆以及出堆)
#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
void swap(int* a, int* b)
{
int c = *a;
*a = *b;
*b = c;
}
void ShiftDown(int* Num, int Now, int Last)//一次向下调整
{
int Max = Now;
if (Now * 2 <= Last)
{
Max = Now * 2;
if (Now * 2 + 1 <= Last && Num[Now * 2 + 1] < Num[Max])
Max = Now * 2 + 1;
if (Num[Max] < Num[Now])
{
swap(Num + Now, Num + Max);
ShiftDown(Num, Max, Last);
}
}
}
int Pop(int* Num, int* Last)//出堆
{
int Temp = Num[1];
int Now = Num[*Last];
Num[1] = Now;
ShiftDown(Num, 1, *Last - 1);
(*Last)--;
return Temp;
}
int main()
{
int n, k;
cin >> n >> k;
int L = n;
int* Num = new int[n + 1];
for (int i = 1; i <= n; i++)
{
cin >> Num[i];
}
for (int i = n / 2; i >= 1; i--)
ShiftDown(Num, i, n);//调整建堆
int Temp;
for (int i = 1; i <= k + 1; i++)
Temp = Pop(Num, &n);
cout << Temp;
return 0;
}
但是不负众望,他还是TLE了,草泥马
然后,想起来输入输出也会影响,我就把C++的输入输出流cin和cout改为了C的标准输入输出scanf以及printf,然后就发生了神奇的现象,就改了输入输出,但是原先的代码AC了!!!呜呼呜呼
所以,在一些数据输入输出量很多的题里,如果TLE了可以尝试将cin和cout改为scanf以及printf!!!!而且听说getchar会更快
最后来说一下这道题的另一种做法,或者说题干推荐的做法?,分治或者说二分,利用快排的思想去找而不是进行整体的快速排序
#include<iostream>
#include<cstdio>
using namespace std;
void Swap(int* a, int* b)
{
int c = *a;
*a = *b;
*b = c;
}
int FindK(int* Num, int Begin, int Last, int k)
{
int Temp = Num[Begin];
int L = Begin; int R = Last;
while (L < R)
{
for (; Num[R] >= Temp && L < R; R--);
for (; Num[L] <= Temp && L < R; L++);
Swap(Num + R, Num + L);
}
Swap(Num + L, Num + Begin);//一次快排,所有比Temp小的都在Temp的左边,比Temp大的都在Temp右边
//而L(R)正好是比Temp小的元素个数,若K>L,则从L右边部分继续去找第K小,K<L,从右边找,K==L,说明找到了,输出
//所以只需要比较元素个数与K的大小就可以确定在那部分去寻找第K小的元素
if (k > L)
return FindK(Num, L + 1, Last, k);//去右边查找
else if (k < L)
return FindK(Num, Begin, L - 1, k);//去左边查找
else if (k == L)
return Num[k];//若正好,直接输出
}
int main()
{
int n, k;
scanf("%d %d", &n, &k);
int* Num = new int[n];
for (int i = 0; i < n; i++)
scanf("%d", Num + i);
printf("%d", FindK(Num, 0, n - 1, k));
return 0;
}
这样的话不需要去快排整个序列而是通过不断的二分查找去找部分的快排后的数据,来找第K小的数,比直接sort快多了,时间复杂度O(n),而快排时间复杂度O(nlogn)
洛谷P1923 求第K小的数 研讨关于输入输出效率的问题(scanf and cin ,printf and cout)的更多相关文章
- 求第k小的数
题目链接:第k个数 题意:求n个数中第k小的数 题解: //由快速排序算法演变而来的快速选择算法 #include<iostream> using namespace std; const ...
- *HDU2852 树状数组(求第K小的数)
KiKi's K-Number Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- [LeetCode] 4. Median of Two Sorted Arrays(想法题/求第k小的数)
传送门 Description There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the m ...
- 【题解】洛谷P1066 [NOIP2006TG] 2^k进制数(复杂高精+组合推导)
洛谷P1066:https://www.luogu.org/problemnew/show/P1066 思路 挺难的一道题 也很复杂 满足题目要求的种数是两类组合数之和 r的最多位数m为 w/k(当w ...
- 【洛谷p1066】2^k进制数
(不会敲键盘惹qwq) 2^k进制数[传送门] 算法标签: (又是一个提高+省选-的题) 如果我说我没听懂你信吗 代码qwq: #include<iostream> #include< ...
- 求第k小的数 O(n)复杂度
思路:利用快速排序的思想,把数组递归划分成两部分.设划分为x,数组左边是小于等于x,右边大于x.关键在于寻找一个最优的划分,经过 Blum . Floyd . Pratt . Rivest . Tar ...
- 基于快速排序思想partition查找第K大的数或者第K小的数。
快速排序 下面是之前实现过的快速排序的代码. function quickSort(a,left,right){ if(left==right)return; let key=partition(a, ...
- 【新知识】队列&bfs【洛谷p1996约瑟夫问题&洛谷p1451求细胞数量】
(是时候为五一培训准备真正的技术了qwq) part1 队列(FIFO) 算法简介: FIFO:First In First Out(先进先出) 队列是限定在一端进行插入,另一端进行删除的特殊线性表 ...
- 洛谷P2464 [SDOJ2008]郁闷的小J
洛谷P2464 [SDOJ2008]郁闷的小J 题目描述 小J是国家图书馆的一位图书管理员,他的工作是管理一个巨大的书架.虽然他很能吃苦耐劳,但是由于这个书架十分巨大,所以他的工作效率总是很低,以致他 ...
- 树状数组求第k小的元素
int find_kth(int k) { int ans = 0,cnt = 0; for (int i = 20;i >= 0;i--) //这里的20适当的取值,与MAX_VAL有关,一般 ...
随机推荐
- Nacos注册中心搭建
1.Nacos服务端搭建(需要有java环境),下载地址:https://github.com/alibaba/Nacos/releases 下载对应操作系统的包解压. 1.1.解压:tar -zxv ...
- SpringBoot AOP 记录操作日志、异常日志
使用SpringBoot AOP 记录操作日志.异常日志 我们在做项目时经常需要对一些重要功能操作记录日志,方便以后跟踪是谁在操作此功能.在操作某些功能时也有可能会发生异常,但是每次发生异常要定位原因 ...
- 开源项目《Elight.MVC-ASP.NET》的研究学习
一 观看效果 将源码下载来后,发现不能直接运行,读了一下md文件,发现还要做自己一些改动. 由于我本机是sqlserver, 所以我改了下 appsetting.json 里要使用的数据库,然后 ...
- 解决pyintstaller 打包后程序报错 api-ms-win-core-path-l1-1-0.dll文件
一.错误现象 1.api-ms-win-core-path-l1-1-0.dll错误日志如下: 2.重新打包查看有如下的警告信息: 二.解决方案: 1.网上下载:api-ms-win-core-pat ...
- SV task and function
内容 system verilog过程语句:自增和自减操作符 逻辑比较操作符 逻辑值为1bit inside语句 变量类型转换 强制类型转换:$cast() 变量位宽转换 变量符号位转换 for循环语 ...
- Nginx 配置文件备忘单
Nginx 是用于 Web 服务.反向代理.缓存.负载平衡.媒体流等的开源软件.在这篇文章中,我将提到一些我们经常使用的 Nginx 配置. 监听端口 server { Standard HTTP P ...
- UofTCTF 2024 比赛记录
这次的题目挺有意思,难度适中,*开头的代表未做出,简单记录一下解题笔记. Introduction General Information 题目 The flag format for all cha ...
- [转帖]SQL Server索引的维护 - 索引碎片、填充因子
https://www.cnblogs.com/kissdodog/archive/2013/06/14/3135412.html 这两个问题都和页密度有关,虽然两者的表现形式在本质上有所区别,但是故 ...
- TiDB恢复部分表的方式方法
TiDB恢复部分表的方式方法 背景 今天同事告知误删了部分表. 因为是UAT准生产的环境, 所以仅有每天晚上11点的备份处理. 同时告知 昨天的数据也可以. 得到认可后进行了 TiDB的单表备份恢复. ...
- [转帖]Oracle如何重启mmon/mmnl进程(AWR自动采集)
https://www.cnblogs.com/jyzhao/p/10119854.html 学习一下 环境:Oracle 11.2.0.4 RAC现象:sysaux空间满导致无法正常生成快照,清理空 ...