算法训练 区间k大数查询

来源:互联网 发布:傲虎网络 编辑:程序博客网 时间:2024/05/19 22:46
  算法训练 区间k大数查询  
问题描述

给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个。

输入格式

第一行包含一个数n,表示序列长度。

第二行包含n个正整数,表示给定的序列。

第三个包含一个正整数m,表示询问个数。

接下来m行,每行三个数l,r,K,表示询问序列从左往右第l个数到第r个数中,从大往小第K大的数是哪个。序列元素从1开始标号。

输出格式
总共输出m行,每行一个数,表示询问的答案。
样例输入
5
1 2 3 4 5
2
1 5 2
2 3 2
样例输出
4
2
数据规模与约定

对于30%的数据,n,m<=100;

对于100%的数据,n,m<=1000;

保证k<=(r-l+1),序列中的数<=106

下面附上鄙人写的代码,正确但是感觉有瑕疵。

#include<iostream>#include<algorithm>using namespace std;int main(){int n,a[1005],m,l,r,k,i,j,c,nl,nr;cin>>n;for(i=0;i<n;i++)cin>>a[i];          //这是一个原数组,我们不能直接在上面排序,因为下面有多次排序。 cin>>m;for(i=0;i<m;i++){    cin>>l>>r>>k;    int count=1;    int copy[n];    //创建一个copy[]数组,每次排序之前都要拷贝原有还没有排序的数组。    for(c=0;c<n;c++)    {        copy[c]=a[c];     }     nl=l-1,nr=r;    sort(copy+nl,copy+nr);    for(j=r-1;j>=l-1;j--)//j就是下标     {        if(count==(k))        {            cout<<copy[j]<<endl;            break;        }        count++;    } }     return 0; }  //只过了30%的数据。 程序没有错,之所以只是过了30%,是因为之前声明的数组不够大 //重新把数组声明为a[1005],之后就满分通过评测。 

上面代码写得感觉不够优雅!

下面附上某大神的代码。

// k 大数查询#include <iostream>#include <algorithm>using namespace std;int arr[1001],brr[1001];bool cmp(int a,int b){    return a>b;}int main(){    int n,m;    int l,r,k;    int i,j;    while(cin>>n)    {        for(i=0;i<n;++i)            cin>>arr[i];        cin>>m;        while(m--)        {            cin>>l>>r>>k;            // 将相应的区间复制到另一个数组中,排序            for(j=l-1,i=0;j<r;++j,++i)                brr[i]=arr[j];            sort(brr,brr+i,cmp);            cout<<brr[k-1]<<endl;                   }    }    return 0;}
原创粉丝点击