问题描述
给定一个序列,每次询问序列中第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
1 2 3 4 5
2
1 5 2
2 3 2
样例输出
4
2
2
数据规模与约定
对于30%的数据,n,m<=100;
对于100%的数据,n,m<=1000;
保证k<=(r-l+1),序列中的数<=106。
思维分析:
首先需要对输入的数据进行对应区间的排序,才能每次都找到对应区间每个数对应的排名,也就可以输出对应的区间K大值。
首先是排序算法,排序算法分为很多种,由于本题的数据比较简单,所以采用的是简单快速排序法,下面是简单排序算法的C++代码:
void Swap(int &a,int &b){//使用引用,对两个数进行交换 int temp=0; temp=a; a=b; b=temp; } void sortj(int a[],int n){//排序算法降序 int i,j,t,temp; for(i=0;i<n;i++){ t=i; for(j=i;j<n;j++){ if(a[t]<a[j]) t=j; } Swap(a[t],a[i]); } }
然后我们用到的是对应每个区间的数组拷贝的函数,通过这个函数将每次的区间数组都进行一次确认,以方便以后的排序以及输出;代码如下:
void copyArr(int a[],int b[],int begin,int end){ int i,j=0; for(i=begin-1;i<=end-1;i++){ b[j]=a[i]; j++; } }
最后就是整个程序的总体代码送给大家,仅供参考,由于本人是在校学生所以代码的规范性有很大的不足,希望各位大佬别介意啊!不懂的下面留言,我会及时回复;
#include <iostream> using namespace std; /* *程序功能:输入一组数据,再输入一组二维数据 *查找出l-r中间第K大的元素并输出 */ void Swap(int &a,int &b){//使用引用,对两个数进行交换 int temp=0; temp=a; a=b; b=temp; } void sorts(int a[],int n){//排序算法升序 int i,j,t,temp; for(i=0;i<n;i++){ t=i; for(j=i;j<n;j++){ if(a[t]>a[j]) t=j; } Swap(a[t],a[i]); } } void sortj(int a[],int n){//排序算法降序 int i,j,t,temp; for(i=0;i<n;i++){ t=i; for(j=i;j<n;j++){ if(a[t]<a[j]) t=j; } Swap(a[t],a[i]); } } //将各区间的进行拷贝到另外一个数组 void copyArr(int a[],int b[],int begin,int end){ int i,j=0; for(i=begin-1;i<=end-1;i++){ b[j]=a[i]; j++; } } int main(){ int n,arr[100000],m; int a[100000][3];//查询二维数组 int ar[100000];//备用拷贝数组 cin>>n; for(int i=0;i<n;i++){ cin>>arr[i]; } cin>>m;//需要查询的次数 for(int i=0;i<m;i++){//输入每次查询的序列存储在二维数组 for(int j=0;j<3;j++){ cin>>a[i][j]; } } for(int i=0;i<m;i++){ copyArr(arr,ar,a[i][0],a[i][1]); sortj(ar,a[i][1]-a[i][0]+1); cout<<ar[a[i][2]-1]<<endl; } return 0; }