蓝桥杯练习系统-区间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

思维分析:

首先需要对输入的数据进行对应区间的排序,才能每次都找到对应区间每个数对应的排名,也就可以输出对应的区间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;
} 

猜你喜欢

转载自blog.csdn.net/qq_26086823/article/details/80050844