P1138 第 k 小整数
题目描述
现有 n 个正整数,要求出这 n 个正整数中的第 k 个最小整数(相同大小的整数只计算一次)。
输入格式
第一行为 n 和 k; 第二行开始为 n 个正整数的值,整数间用空格隔开。
输出格式
第k个最小整数的值;若无解,则输出 NO RESULT
。
输入输出样例
输入 #1
10 3 1 3 3 7 2 5 1 2 4 6
输出 #1
3
说明/提示
≤10000n≤10000,≤1000k≤1000,正整数均小于 3000030000。
看一下代码
解法1
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
struct pt{
int sum;
pt* ch[2];
};
typedef pt* ptr;
ptr root[maxn];
int n,k;
void add(ptr last,ptr& th,int v,int l=1,int r=n){
th=new pt;
*th=*last;
th->sum=last->sum+1;
if(l==r)return ;
int mid=l+r>>1;
if(v<=mid)add(last->ch[0],th->ch[0],v,l,mid);
else add(last->ch[1],th->ch[1],v,mid+1,r);
}
int getid(ptr le,ptr re,int k,int l=1,int r=n){
if(l==r)return l;
int tmp=re->ch[0]->sum-le->ch[0]->sum;
int mid=l+r>>1;
if(k<=tmp)return getid(le->ch[0],re->ch[0],k,l,mid);
else return getid(le->ch[1],re->ch[1],k-tmp,mid+1,r);
}
int a[maxn];
int main(){
ptr& null=root[0];
null=new pt;
null->ch[0]=null->ch[1]=null;null->sum=0;
cin>>n>>k;
for(int i=1;i<=n;++i){
cin>>a[i];
}
sort(a+1,a+1+n);
n=unique(a+1,a+1+n)-a-1;
if(k>n){
cout<<"NO RESULT"<<endl;
return 0;
}
for(int i=1;i<=n;++i){
add(root[i-1],root[i],i);
}
cout<<a[getid(root[0],root[n],k)]<<endl;
return 0;
}
考点分析
这道题其实主要考点是 c++函数语法,整体来说不难,只要记住函数名即可
这里用到的几个函数名大家应该都不陌生。
我来重点说一下解法2
STL函数————unique
就是把数组伪去重,重复的数放在数组末
看代码
#include<bits/stdc++.h>
using namespace std;
int n,k,a[10000];
int main()
{
cin>>n>>k;
for(int i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);
int ans=unique(a,a+n)-a;//给数组a去重,并保留ans=去重后非伪的长度
if(k<ans)
cout<<a[k-1]; //如果去重以后k<=ans,则输出对应的数
else cout<<"NO RESULT";//否则
return 0;
}
谢谢关注