洛谷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有关,一般 ...
随机推荐
- vue学习笔记 八、toRef的使用
系列导航 vue学习笔记 一.环境搭建 vue学习笔记 二.环境搭建+项目创建 vue学习笔记 三.文件和目录结构 vue学习笔记 四.定义组件(组件基本结构) vue学习笔记 五.创建子组件实例 v ...
- 【转载】内存基本概念-node, zone ,page
1. Linux描述物理内存 在linux 内存管理(一)中介绍了UMA和NUMA,Linux通过巧妙办法把UMA和NUMA的差别隐藏了起来,所谓的UMA其实就是只有一个结点的NUMA.内存的每个结点 ...
- freeswitch透传带SDP的180
概述 freeswitch是一款简单好用的VOIP开源软交换平台. freeswitch对于180/183的消息处理有默认的规则,但是在3GPP的标准中,消息流程会更加复杂,场景更多变. 这样就需要我 ...
- freeswitch服务器的时间同步设置
概述 在生产环境中,一般会有N台freeswitch 服务器,不同服务器之间的信令和话单的时间不能相差太多,否则对查找和定位问题会造成一定的困扰. 同时,freeswitch的默认运行设置并未直接使用 ...
- SD Host控制器的datasheet
SD-Host控制器的datasheet更多的是给嵌入式软件工作人员使用,datasheet中主要包含一些寄存器以及读写擦除流程 寄存器主要有: 控制寄存器 状态寄存器 配置寄存器 软件和硬件进行交互 ...
- 【C/C++】函数入参检查
// 统计变参数量 #define CALC_VA_COUNT(arg...) \ ({ \ int count = 0; \ int insideQuotes = 0; \ const char * ...
- python环境 anaconda安装
官网: https://www.anaconda.com/distribution/#macos 国内镜像: https://mirrors.tuna.tsinghua.edu.cn/anaconda ...
- Go-包-package-modules-import
- [转帖]Unicode与utf的前世今生
https://www.cnblogs.com/naodong/p/12742987.html 历史上存在两个独立的尝试创立单一字符集的组织,即 国际标准化组织(ISO)于1984年创建的通用字符集( ...
- [转帖]前后台切换命令(ctrl+z jobs bg fg &)
当我在终端里面运行某个命令的时候,结果不是很快就能出来的那种,或者是一大堆字在屏幕上狂翻.这个时候,有时ctrl+c也不起作用,那我会用ctrl+z退出来,这个很有效,但是说实话我不知道为什么这个可以 ...