资源限制
时间限制: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的!