问题描述
给出一个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个数中不大于它的个数,以此类推
解题思路:先用n行m列矩阵形成一个二维数组对照值,用每个数与每个数作对比,若大于等于,则矩阵目标值加1即可,否则等于原值,最后取区间只要取两值之差即可
举例输入5个整数为52341,产生结果如下表所示
– | 5 | 2 | 3 | 4 | 1 |
---|---|---|---|---|---|
5 | 1 | 2 | 3 | 4 | 5 |
2 | 0 | 1 | 1 | 1 | 2 |
3 | 0 | 1 | 2 | 2 | 3 |
4 | 0 | 1 | 2 | 3 | 4 |
1 | 0 | 0 | 0 | 0 | 1 |
源代码如下:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
Reader sc=new Reader();
int n=sc.nextInt();
int m=sc.nextInt();
int[] a=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
int [][]b=new int [n][n+1];
for(int i=0;i<n;i++) {
for(int j=0;j<n;j++) {
if(a[i]>=a[j]) {
b[i][j+1]+=b[i][j]+1;
}else {
b[i][j+1]=b[i][j];
}
}
}
for(int i=0;i<m;i++) {
int l1=sc.nextInt();
int r1=sc.nextInt();
int l2=sc.nextInt();
int r2=sc.nextInt();
for(int j=l2;j<=r2;j++) {
System.out.print(b[j-1][r1]-b[j-1][l1-1]+" ");
}
System.out.println();
}
}
/** 快速输入类 */
static class Reader {
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer tokenizer = new StringTokenizer("");
/** 获取下一段文本 */
static String next() throws IOException {
while ( ! tokenizer.hasMoreTokens() ) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt( next() );
}
static double nextDouble() throws IOException {
return Double.parseDouble( next() );
}
}
}