第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1 算法训练 区间k大数查询

简介: 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1 算法训练 区间k大数查询

第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1 算法训练 区间k大数查询


前言

       最近的一些文章都可能会很碎,写到哪里是哪里,过一阵子会具体的整理一遍,这里其它的类型题先往后排一排,因为蓝桥最后考的也就是对题目逻辑的理解能力,也就是dp分析能力了,所以就主要目标定在这里,最近的题目会很散,很多,基本上都是网罗全网的一些dp练习题进行二次训练,准备比赛的学生底子薄的先不建议看啊,当然,脑子快的例外,可以直接跳过之前的一切直接来看即可,只需要你在高中的时候数学成绩还可以那就没啥问题,其实,dp就是规律总结,我们只需要推导出对应题目的数学规律就可以直接操作,可能是一维数组,也可能是二维数组,总体来看二维数组的较多,但是如果能降为的话建议降为,因为如果降为起来你看看时间复杂度就知道咋回事了,那么在这里祝大家能无序的各种看明白,争取能帮助到大家。


算法训练 区间k大数查询

资源限制

内存限制:256.0MB   C/C++时间限制:1.0s   Java时间限制:3.0s   Python时间限制:5.0s

问题描述

给定一个序列,每次询问序列中第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),序列中的数<=10^6

题解:

C语言

#include <stdio.h>  
 #include <stdlib.h>  
 int Split(int *data,int pre,int rear)  
 {  
     int value=data[pre];  
     while(pre<rear)  
     {  
         while(data[rear]>=value && pre<rear) rear--;  
         data[pre]=data[rear];  
         while(data[pre]<value && pre<rear) pre++;  
         data[rear]=data[pre];  
     }  
     data[pre]=value;  
     return pre;  
 }  
 //快速排序  
 void QuickSort(int *data,int pre,int rear,int k)  
 {  
     if(pre<=rear)  
     {  
         int mid=Split(data,pre,rear);  
         if(mid==k)  
         {  
             printf("%d\n",data[mid]);  
         }  
         else if(mid>k)  
         {  
             QuickSort(data,pre,mid-1,k);  
         }  
         else  
         {  
             QuickSort(data,mid+1,rear,k);  
         }  
     }  
 }  
 void Copy(int *data,int n,int *temp)  
 {  
     int i;  
     for(i=0;i<n;i++)  
     {  
         temp[i]=data[i];  
     }  
 }  
 int main()  
 {  
     int i;  
     int n;  
     int m;  
     int *data;  
     scanf("%d",&n);  
     data=(int *)malloc(sizeof(int)*n);  
     for(i=0;i<n;i++)  
     {  
         scanf("%d",&data[i]);  
     }  
     scanf("%d",&m);  
     while(m)  
     {  
         int pre;  
         int rear;  
         int k;  
         int *temp=(int *)malloc(sizeof(int)*n);  
         scanf("%d%d%d",&pre,&rear,&k);  
         Copy(data,n,temp);  
         QuickSort(temp,pre-1,rear-1,rear-k);  
         m--;  
     }  
     return 0;  
 }

C++语言

#include<stdio.h>
#include<algorithm>
using namespace std;
#define N 10005
int n,m;
int a[N],tree[15][N],sum[15][N];
bool cmp(int x,int y)
{
  return x>y;
}
void build(int x,int L,int R)
{
  if(L==R)  return;
  int i;
  int mid=(L+R)>>1;
  int lp=L,rp=mid+1,l=mid-L+1;
  for(i=L;i<=R;i++)
    if(tree[x][i]>a[mid])
      l--;
  for(i=L;i<=R;i++)
  {
    sum[x][i]=i==L?0:sum[x][i-1];
    if(a[mid]==tree[x][i] && l)
    {
      l--;
      tree[x+1][lp++]=tree[x][i];
      sum[x][i]++;
    }
    else
    if(tree[x][i]>a[mid])
    {
      tree[x+1][lp++]=tree[x][i];
      sum[x][i]++;
    }
    else
      tree[x+1][rp++]=tree[x][i];
  }
  build(x+1,L,mid);
  build(x+1,mid+1,R);
}
int query(int x,int L,int R,int l,int r,int k)
{
  if(l==r)  return tree[x][l];
  int mid=(L+R)>>1;
  int t,tt;
  t=l==L?0:sum[x][l-1];
  tt=sum[x][r]-t;
  if(k<=tt)
    return query(x+1,L,mid,L+t,L+t+tt-1,k);
  else
    return query(x+1,mid+1,R,mid-L+1+l-t,mid-L+1+r-t-tt,k-tt);
}
int main()
{
  scanf("%d",&n);
  for(int i=1;i<=n;i++)
  {
    scanf("%d",&a[i]);
    tree[0][i]=a[i];
  }
  sort(a+1,a+1+n,cmp);
  build(0,1,n);
  scanf("%d",&m);
  int l,r,k;
  while(m--)
  {
    scanf("%d%d%d",&l,&r,&k);
    printf("%d\n",query(0,1,n,l,r,k));
  }
  return 0;
}

Java语言

这里看好扫描器的使用啊,数据录入不是很方便。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
  public static void main(String[] args) {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    try {
      int n = Integer.parseInt(br.readLine());
      int[] arr = new int[n+1];
      
      String[] s = br.readLine().split(" ");
      for (int i = 1; i < arr.length; i++) {
        arr[i] = Integer.parseInt(s[i-1]);
      }
      int m = Integer.parseInt(br.readLine());
      String[] s1;
      int[][] brr = new int[m][3];
      for (int i = 0; i < m; i++) {
        s1 = br.readLine().split(" ");
        for (int j = 0; j < s1.length; j++) {
          brr[i][j] = Integer.parseInt(s1[j]);
        }
      }
      int a;
      int b;
      int c;
      for (int i = 0; i < m; i++) {
        a = brr[i][0];
        b = brr[i][1];
        c = brr[i][2] - 1;
        int[] brr1 = new int[b - a + 1];
        System.arraycopy(arr, a, brr1, 0, b - a + 1);
        shellSort(brr1);
        System.out.println(brr1[b - a - c]);
      }
    } catch (IOException e) {
      e.printStackTrace();
    }finally {
      try {
        br.close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
  }
  
  public static void shellSort(int[] arr) {
      for (int gap = arr.length / 2; gap > 0; gap /= 2) {
          for (int i = gap; i < arr.length; i++) {
              int j = i; 
              int temp = arr[j]; 
              if (arr[j] < arr[j - gap]) {
                  while (j - gap >= 0 && temp < arr[j - gap]) {
                      arr[j] = arr[j - gap];
                      j -= gap; 
                  }
                  arr[j] = temp;
              }
          }
      }
  }
}

Python语言

我们已经不是1次两次看到列表推导式了,应该已经不陌生了,有时间可以专门的捉摸一下列表推导式,很方便好用。

n = input()
n_list = list(map(int,input().split()))
m = int(input())
Ls = []
for i in range(m):
    Ls.append(list(map(int,input().split())))
for j in Ls:
    l=int(j[0])-1
    r=int(j[1])
    k=int(j[2])- 1
    result = sorted(n_list[l:r],reverse=True)
    print(result[k])

没有什么不付出就能拿到的结果,我们都是在负重前行,最终结果与自身先天的脑力有一定的关系,但是还是有很大一部分看自己后天的努力,其实从报名到比赛也就5个月左右,真正刷题的事件也就2个月,2个月回忆一下你真正的认真刷过题吗,如果你真的用尽所有的精力去努力了,那么我相信你最终的成绩一定会让你满意的,加油。


相关文章
|
27天前
|
算法 测试技术 C++
【动态规划算法】蓝桥杯填充问题(C/C++)
【动态规划算法】蓝桥杯填充问题(C/C++)
|
20天前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
36 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
5月前
|
存储 机器学习/深度学习 算法
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
第十五届蓝桥杯pb组国赛E题[马与象] (15分)BFS算法 详解
53 3
|
14天前
|
算法 Java 程序员
【算法每日一练及解题思路】有n级台阶,一次只能上1级或2级,共有多少种走法?
本文深入解析了“爬楼梯问题”,探讨了递归与迭代两种解法,并提供了Java代码实现。通过分析问题本质,帮助读者理解动态规划技巧,提高解决实际编程问题的能力。关键词:Java, 算法, 动态规划, 爬楼梯问题, 递归, 迭代。
33 0
|
27天前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)二
41 2
|
6月前
|
存储 算法 Java
蓝桥杯递归算法
蓝桥杯中的递归算法涉及将问题分解为子问题,通过函数自身调用来求解。优点是简洁易懂,但效率低且可能引发栈溢出。示例包括:数组求和、数的阶乘、斐波那契数列及最大公约数计算,以及字符串翻转。代码展示了各种递归场景的Java实现,如`f3`计算数组和,`f`求阶乘,`f1`计算斐波那契数,`f2`找最大公约数,和`f1`字符串反转。
34 1
|
5月前
|
人工智能 算法 搜索推荐
蓝桥杯宝藏排序题目算法(冒泡、选择、插入)
以下是内容的摘要: 本文介绍了三种排序算法:冒泡排序、选择排序和插入排序。冒泡排序通过不断交换相邻的逆序元素逐步排序,最坏情况下需要 O(n^2) 次比较。选择排序在每轮中找到剩余部分的最小元素并放到已排序序列的末尾,同样具有 O(n^2) 时间复杂度。插入排序则是将每个元素插入到已排序序列的正确位置,时间复杂度也是 O(n^2),但空间复杂度为 O(1)。
|
6月前
|
算法 安全
死锁相关知识点以及银行家算法(解题详细步骤)
死锁相关知识点以及银行家算法(解题详细步骤)
226 2
|
5月前
|
算法 C语言
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
数据结构和算法学习记录——栈和队列习题-用队列实现栈、用栈实现队列(核心思路、解题过程、完整题解)一
35 0