洛谷P1138第k小数——题解(最最最简单易懂版)

本文是一篇题解,包含正解代码,时间复杂度不是最优的,但是 最简单易懂😜


题面
现有 n 个正整数,要求出这 n 个正整数中的第 k 个最小整数(相同大小的整数只计算一次)。

输入格式
第一行为 n 和 k; 第二行开始为 n 个正整数的值,整数间用空格隔开。

输出格式
第k个最小整数的值;若无解,则输出 "NO RESULT"。

输入样例
10 3
1 3 3 7 2 5 1 2 4 6

输出样例
3

说明/提示
n≤10000,k≤1000,正整数均小于 30000。


这个题意真的非常直白了,就是找第k小的数,就不多解释了

思路
要找第k小的数,首先数列得有序,so,

🔴first step:排序(我这里采用非常原始的sort()函数)

这一步排序其实不用太细致,sort()是不去重的。
这里个大家推荐一个能起到去重效果的函数unique(); 这个函数的详细信息在这里
👍https://blog.csdn.net/weixin_45031801/article/details/137522007
助理,我要在十秒内得到unique函数的全部信息🤣

🟠second step:顺着排好的数列找第k小数是啥

这一步注意,数列没去重

🟡third step:找到了就输出呀,输出了就完了呀(找不到输出没结果)


接下来是代码 没注释可直接copy版

点击查看代码👀
#include<bits/stdc++.h>
using namespace std;
int n,k,m;
int a[10005];
int main()
{
	cin>>n>>k;
	
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	
	sort(a,a+n+1);
	m=a[1];
	for(int i=1;i<=n;i++)
	{
		if(k==1)
		{
			cout<<a[i-1];
			return 0;
		}
		if(a[i]!=m)
		{
			k--;
			m=a[i];
		}
		
	}
	cout<<"NO RESULT";
	return 0;
}

接下来这个是带注释版本的(里面有一些small details🤏拿捏👌):

点击查看代码👀
#include<bits/stdc++.h>//万能头偷懒 
using namespace std;
int n,k,m;
int a[10005];//数组这个大小足够了,题目中说了n≤10000,k≤1000 
int main()
{
	cin>>n>>k;//输入,一共的数字个数,找的是第几小 
	
	for(int i=1;i<=n;i++)//循环输入给出的数列 
	{
		cin>>a[i];//存到了a数组里 
	}
	
	sort(a,a+n+1);//sort快排函数(自带的不用你写) 
//这里后面有加一是因为前面输入的a数组是从a[1]开始的 

/*样例中排序过后的数组长这样:

1 1 2 2 3 3 4 5 6 7 

*/ 
	
	
//-----------------下面就是找第k小了------------------- 

	
	
	m=a[1];//(这句注释一会儿回来再看 这样思路更顺) 这个给m有个初始值,一开始就在最小的数的范围内 
	
	for(int i=1;i<=n;i++)
	{
		if(k==1)//(这句注释适合一会儿回头看) 当k==1的时候,就找到第k小数了 
		{
			cout<<a[i-1];//这里输出的是a[i-1],因为当情况发生到第(k-1)次的时候,就已经到了第k+1小数范围的第一个数了,so,i-1输出上一个数就解决了 
			return 0;
		}
				/*
    ---------------------以下是下面五行代码思路讲解------------------
		
				因为没有去重所以不能简单输出a[k],如果用unique去重的话当我没说 
				我这里采用的是一个笨笨的思路: 
				因为排序,把相同数字都聚集在了一起,还是由小到大的顺序, 
				所以只要上一个和这个不同,就说明这个是一个新的更大的数字,
				不相同这种情况要出现几次呢(如果查询起点是a[1]的话)?
				只需要(k-1)次就行。
				
				于是乎,就有了下面五行代码。
				
				*/ 
		if(a[i]!=m)//比较两个不同的情况出现几次,当然需要两个比较对象了,我这里采用的方法笨笨的,用m表示之前最近一次出现过的数字,用新的与m相比,如果不一样,就说明找到了一个新的数字 
		{
			k--;//这里需要记录情况出现的次数,需要一个计数器,(k-1)表示的就是情况出现次数,出现一次情况就将k剪掉一个,所以当k数值为1时,就算是找到了(此处回到上面k==1那句) 
			m=a[i];
		}
		
	}
	cout<<"NO RESULT";//唉???这句为什么不加个特判啊 ?因为上面已经有一句return 0;了,如果过上面循环体中的条件能找到第k小数的话,早都输出并且结束了,根本运行不到这里。能运行到这里,只能是找不到k小数,输出个没结果就行了 
/*	那么为什么会出现找不到第k小数的情况呢?
	
	举个例子就明白了:
	假如输入是
	10 3
	1 1 1 1 2 1 1 2 1 1
	让找的是第3小的数,但是事实上只有1这个第一小和2这个第2小,没有第3小 
	
	
*/	 
	return 0;
	
//over!!!
//祝您A题愉快 
	
}

看完了,点个赞呗🥺

posted @ 2025-05-03 18:09  一只好好好好猫  阅读(174)  评论(0)    收藏  举报