蓝桥杯 算法训练(一)区间k大数查询 C语言
区间k大数查询 C语言
问题描述
给定一个序列,每次询问序列中第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。
这道题是在前面序列排序基础上的一道应用题,题目要求有点繁杂,需要读者仔细看题,看懂了这道题其实也不会很难。
笔者的想法很简单,就是先输入一串序列作为原始序列,在将要求询问的区间取出放到备份序列中。
注意:这里根据题目要求可知,我们不止要询问一次答案,而是询问m次!
所以原始序列 a[] 必须反复使用,因此我们一定不能对 a[] 做任何改动,每次询问答案时,应该先将要询问的区间放到备份序列b[]上,再对b[] 进行排序。
不懂的读者可以自己思考一下,这一点其实很容易能明白的。笔者写太多,担心读者更加难懂。
下面直接贴代码:
#include <stdio.h>
void bubble_sort(int a[], int n) //冒泡排序 顺序为从大到小排列
{
int i,j,temp;
for(j=0;j<n-1;j++)
{
for(i=0;i<n-1-j;i++)
{
if(a[i]<a[i+1])
{
temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
}
}
}
}
int main() {
int n,m,l,r,k;
int i,j; //用于循环
scanf("%d",&n); //输入n值,表示序列长度
int a[n],b[n]; //a[n]为原始序列,b[n]为备份序列,用于排序操作
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
} //输入一串序列
scanf("%d",&m); //输入询问个数m;
for(i=0;i<m;i++)
{
int num=0;
scanf("%d%d%d",&l,&r,&k); //输入l,r、k的值 ,l为询问起始位置,r为询问结束位置,k为询问区间内第k大的数
for(j=l-1;j<r;j++)
{
b[num++]=a[j];
} //将需要询问的区间取出备份到b[]序列
bubble_sort(b,num);
printf("%d\n",b[k-1]); //直接输出第k大的数,注意:第一大的数为b[0],所以用 k-1;
}
return 0;
}
做这道题有两个地方要注意:
1、要注意序列的第一个数是放在数组的哪一个位置,笔者的代码中都是从数组的0位开始放的这一点非常重要,千万不能乱了。
2、笔者的代码中有一个num,要注意一定要把“int num=0”放在for循环中,即每次循环询问,都要将num清零。因为这个小问题,笔者这段代码卡了一整天T_T
笔者查阅了其他博主的答案,感觉自己这段代码相对更好理解一点,非常美滋滋呀~哈哈
其他有什么问题,欢迎读者下方留言~~
最后,有大神可以教教我怎么改变博文的字体大小和颜色吗?感觉默认大小实在太小了,不够显眼,读起来容易造成疲劳呀 ,在此拜谢~~
还没有评论,来说两句吧...