洛谷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题愉快
}
看完了,点个赞呗🥺

浙公网安备 33010602011771号