问题描述
给定一个序列,每次询问序列中第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。
解答:
NO.1
刚开始做,想的复杂了,采用了Set集合类进行解答,只有三个测试用例正确,剩下的发生了未知的错误……
下面贴两段用Set集合类求解的代码:
demo1:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* @author 作者 : Cactus
* @version 创建时间:2018-3-19 下午04:11:24
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //arr's length
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
int m = sc.nextInt(); //how many number should be find
int[][] arr_double = new int[m][3];
for(int i = 0; i < m; i++){
for(int j = 0; j <3; j++){
arr_double[i][j] = sc.nextInt();
}
}
sc.close();
TreeSet<Integer> mySet = new TreeSet<Integer>();
Iterator<Integer> it = mySet.iterator();
int k;
int result;
for(int i = 0; i < m; i++){
for(int j = (arr_double[i][0] - 1); j < arr_double[i][1]; j++){
mySet.add(arr[j]);
}
Object[] arr_result = mySet.toArray();
System.out.println(arr_result[arr_result.length - arr_double[i][2]]);
mySet.clear();
}
}
}
demo2:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;
/**
* @author 作者 : Cactus
* @version 创建时间:2018-3-19 下午04:11:24
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //arr's length
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
int m = sc.nextInt(); //how many number should be find
int[][] arr_double = new int[m][3];
for(int i = 0; i < m; i++){
for(int j = 0; j <3; j++){
arr_double[i][j] = sc.nextInt();
}
}
sc.close();
// TreeSet<Integer> mySet = new TreeSet<Integer>();
// Iterator<Integer> it = mySet.iterator();
// int k;
// int result;
// for(int i = 0; i < m; i++){
// for(int j = (arr_double[i][0] - 1); j < arr_double[i][1]; j++){
// mySet.add(arr[j]);
// }
// Object[] arr_result = mySet.toArray();
// System.out.println(arr_result[arr_result.length - arr_double[i][2]]);
// mySet.clear();
// }
findNum(arr,arr_double);
}
private static void findNum(int[] arr, int[][] arr_double){
TreeSet<Integer> mySet = new TreeSet<Integer>();
int k;
int result = 0;
for(int i = 0; i < arr_double.length; i++){
for(int j = (arr_double[i][0] - 1); j < arr_double[i][1]; j++){
mySet.add(arr[j]);
}
k = arr_double[i][1] - arr_double[i][0] + 1;
Iterator<Integer> it = mySet.iterator();
while(it.hasNext()){
result = it.next();
k--;
if(k == (arr_double[i][2] - 1)){
System.out.println(result);
}
}
mySet.clear();
// 0 1 2 3 4
// 4 3 2 1 0
}
}
}
测试结果如下:
NO.2
大道至简啊,采用最简单的数组就是最佳的求解方法。
代码如下:
import java.util.Arrays;
import java.util.Scanner;
/**
* @author 作者 : Cactus
* @version 创建时间:2018-3-19 下午04:11:24
*/
public class Main {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt(); //arr's length
int[] arr = new int[n];
for(int i = 0; i < n; i++){
arr[i] = sc.nextInt();
}
int m = sc.nextInt(); //how many number should be find
int[][] arr_double = new int[m][3];
for(int i = 0; i < m; i++){
for(int j = 0; j <3; j++){
arr_double[i][j] = sc.nextInt();
}
}
sc.close();
for(int i = 0; i < m; i++){
int length = arr_double[i][1] - arr_double[i][0] + 1;
int[] arr_result = new int[length];
int k = 0;
for(int j = arr_double[i][0] - 1; j < arr_double[i][1]; j++){
arr_result[k] = arr[j];
k++;
}
Arrays.sort(arr_result);
System.out.println(arr_result[length - arr_double[i][2]]);
}
}
}