这个题据说能用快速输入卡时间通过,但是我这里不用,仅在此说一下我做此题的思路,有需要了解快速输入的同学可以自行搜索。
**优先队列思路:
看到这个题,第一感觉是用sort,但是就想试试优先队列,结果只得了
60分
**
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
#define ull unsigned long long
priority_queue<unsigned long long,vector<ull>,greater<ull> > q;
int main()
{
unsigned long long int n,k;
cin >> n >> k;
for(int i=0;i<n;i++)
{
unsigned long long a;
cin >> a ;
q.push(a);
}
for(int i=0;i<n;i++)
{
if(i==k)
{
cout << q.top() << endl ;
break;
}
else q.pop();
}
return 0;
}
然后就气急败坏 直接用nth_element函数+scanf输入(cin输入没有scanf快,cin会超时一丢丢),直接通过
100分
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
#define ull unsigned long long
ull a[5000000];
int main()
{
unsigned long long int n,k;
cin >> n >> k;
for(int i=0;i<n;i++)
{
scanf("%llu",&a[i]);
}
nth_element(a,a+k,a+n);
cout << a[k];
return 0;
}
但是这样肯定不行啊,题上都说了不让用nth_element函数,那要想其他办法了
核心思想是二分。
在原二分的基础上可以进行修改:因为每次递归都会将数组划分为三部分,而答案只会在这三部分中的一个,不需要再对其他部分进行搜索,从而达到优化时间复杂度的效果。
100分
#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
#define ull unsigned long long
int a[5000005],n,k;
int ssort(int l,int r)
{
int i=l,j=r,mid=a[(l+r)/2];
while(i<=j)
{
while(a[i]<mid)i++;
while(a[j]>mid)j--;
if(i<=j)
{
swap(a[i],a[j]);
i++;j--;
}
}
//此时,整个区域被分为3部分,l<=j<=i<=r;
if(k<=j)ssort(l,j);//在左区间搜左区间
else if(i<=k)ssort(i,r);//在右区间搜右区间
else {
cout << a[k] << endl ;
return 0;
}
}
int main()
{
cin >> n >> k;
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
ssort(0,n-1);
return 0;
}