蓝桥杯——ALGO_971 比较_Java

资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
  给出一个n长的数列,再进行m次询问,每次询问询问两个区间[L1,R1],[L2,R2],
  询问数列第L2到R2个数字每一个数在数列第L1到R1个数中有多少个数字不大于它。
输入格式
  第一行两个整数n,m
  第二行n个整数,表示数列。
  接下来m行,每行四个整数L1,R1,L2,R2,意义如上
输出格式
  m行,每行R2-L2+1个整数,第一个整数表示第L2个数在数列第L1到R1个数中不大于它的个数,第一个整数表示第L2+1个数在数列第L1到R1个数中不大于它的个数,以此类推
样例输入
5 3
5 2 3 4 1
1 2 3 4
2 3 1 5
1 5 2 3
样例输出
1 1
2 1 2 2 0
2 3
数据规模和约定
  n,m<=1000,数列的数字非负且小于1000。
  
这道题我首先想到的方法出现了运行超时,导致不能满分,于是想到了第二种方法。

思路①:首先将需要用到的数列,输入到一个一维数组中,然后建立一个二维数组,n行,n+1列(多出来的一列用来帮助计算)

  int [][]arr=new int [n][n+1];
        for(int i=0;i<n;i++) {
            for(int j=0;j<n;j++) {
                if(num[i]>=num[j]) {
                    arr[i][j+1]+=arr[i][j]+1;
                }else {
                    arr[i][j+1]=arr[i][j];
                }
            }
        }

该数组的含义为:遍历整个num数组,使得每个数字依次和其他数字进行比较,如果满足大于等于的条件,则结果为该位置的前一个位置的值+1,不满足条件,则仍然等于前一个位置的值不变。

得到该数组后,对该数组进行遍历,并定义l1 r1 l2 r2 ,然后输出该数组的第l2-1行,r1列的值减第i2-1行,l1-1列的值 即为我们题目要求的结果。

public class Main {
    public  static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        int n = s.nextInt();//n个数
        int m = s.nextInt();//被访问m次
        int num[] = new int[n];
        for (int i = 0; i < n; i++) {
            num[i]=s.nextInt();
        }

        int [][]arr=new int [n][n+1];
        for(int i=0;i<n;i++) {
            for(int j=0;j<n;j++) {
                if(num[i]>=num[j]) {
                    arr[i][j+1]+=arr[i][j]+1;
                }else {
                    arr[i][j+1]=arr[i][j];
                }
            }
        }
        for(int i=0;i<m;i++) {
            int l1=s.nextInt();
            int r1=s.nextInt();
            int l2=s.nextInt();
            int r2=s.nextInt();
            for(int j=l2;j<=r2;j++) {
                System.out.print(arr[j-1][r1]-arr[j-1][l1-1]+" ");
            }
            System.out.println();
        }
    }
}


此种方法会运行超时!!
思路②: 首先将需要用到的数列,输入到一个一维数组中,然后建议一个二维数组,这个二维数组和上面不同,这次需要将l1 r1 l2 r2的数据放到数组中。

然后我们需要一个能够满足题目要求的计算方法:首先定义一个l2,作为下标在num数组中定位用来比较的数,然后用for循环遍历arr数组,外层循环为l2 r2的范围,内存循环为l1 r1的范围,定义一个count ,用来记录我们的结果,在内层循环中判断num数组中的大小关系,如果满足条件则count自增,内层第一次循环完,l2自增,并输出count的值,如果需要被比较的数字已经遍历完,则结束内层循环,如果没有遍历完,则进行第下一个数和num数组中的数字进行比较,直到内层循环完毕。

import java.util.Scanner;
public class Main{
    public static void main(String[] args) {
      Scanner s = new Scanner(System.in);
      int n = s.nextInt();
      int m = s.nextInt();
      int num[] =new int[n];
        for (int i = 0; i < n; i++) {
            num[i]=s.nextInt();
        }
      int arr[][] =new int[m][4];
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < 4; j++) {
                arr[i][j]=s.nextInt();
            }
        }
        int row = 0;
        while (row<m){
            print(num,arr,row);
            System.out.println();
            row++;
        }
    }
    private static void print(int[] num, int[][] arr, int row){
        int l2 = arr[row][2]-1;
        for (int i = 0; i < arr[row][3]-arr[row][2]+1; i++) {
            int count = 0;
            for (int j = arr[row][0]-1; j <=arr[row][1]-1 ; j++) {
                if(num[j]<=num[l2]){
                    count++;
                }
            }
            l2++;
            System.out.print(count+" ");
            if (l2>=num.length){
                break;
            }
        }
    }
}

该方法是可以AC的!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值