【區間最值】、sequence
Sequence
給出一個長度爲N的序列A1,A2, · · · ,AN,其中每項都是小於10^5的自然數。
現在有M個詢問,每個詢問都是Ai · · ·Aj中第k小的數等於多少。
輸入格式
第一行兩個正整數N,M。
第二行N個數,表示序列A1,A2, · · · ,AN。
緊着的M行,每行三個正整數i, j, k(k ≤ j − i + 1),表示詢問Ai...Aj中第k小的數等於多少。
輸出格式
共輸出M行,第i行輸出第i個詢問的答案。
輸入樣例
4 3
4 1 2 3
1 3 1
2 4 3
1 4 4
輸出樣例
1
3
4
數據範圍
在60%的數據中,1 ≤ N ≤ 1000,1 ≤ M ≤ 1000
在100%的數據中,1 ≤ N ≤ 10000,1 ≤ M ≤ 2000
【source】
1.樸素:每次就把這個區間快排,直接輸出第k小的數。這樣只有60、
樸素code
procedure work;
var i,j,k,x,y:longint;
begin
for i:=1 to m do
begin
b:=a;//b爲臨時數組,因爲在這次操作中會改變原數組的順序
readln(x,y,k);
qsort(x,y);
writeln(a[x+k-1]);
a:=b;
end;
end;
2.AC:由於每次詢問只與下標有關,那麼把數據按權值升排後,下標就無序了。
每次讀入一個區間,在有序序列中從左往右掃描,當遇到下標在區間內時,+1、直到這個值等於所求的k就退出、
AC-Code【Java版本】
import java.util.*;
class Number{
int data; //數值
int num; //實際下標
}
class Untitled {
static class mycmp implements Comparator<Number>{
public int compare(Number n1, Number n2){
return n1.data-n2.data;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n,m;
int left,right,find;
n = sc.nextInt();
m = sc.nextInt();
Number[] a = new Number[10000];
for(int i=0;i<n;i++){
a[i] = new Number();
a[i].data = sc.nextInt();
a[i].num = i;
}
//將data排序
Arrays.sort(a, 0, n, new mycmp());
for(int i=0;i<n;i++){
left = sc.nextInt();
right = sc.nextInt();
find = sc.nextInt();
int sum = 0;
for (int j=0;j<n;j++){
if(a[j].num >=left-1 && a[j].num<=right-1){
sum+=1;
if (sum == find ){
System.out.println(a[j].data);
break;
}
}
}
}
}
}
AC-code【Pascal版本】
program sequence;
type node=record
data,num:longint;
end;
var a:array[0..10000]of node;
n,m,left,right,find:longint;
procedure init;
begin
assign(input,'sequence.in');reset(input);
assign(output,'sequence.out');rewrite(output);
end;
procedure endit;
begin
close(input);close(output);
halt;
end;
procedure qsort(s,t:longint);
var i,j:longint;
x,tem:node;
begin
i:=s;j:=t; x:=a[(i+j)div 2];
repeat
while a[i].data<x.data do inc(i);
while a[j].data>x.data do dec(j);
if i<=j then
begin
tem:=a[i];a[i]:=a[j];a[j]:=tem;
inc(i);dec(j);
end;
until i>j;
if s<j then qsort(s,j);
if i<t then qsort(i,t);
end;
procedure main;
var i,j,sum:longint;
begin
readln(n,m);
for i:=1 to n do
begin
read(a[i].data);
a[i].num:=i;
end;
qsort(1,n);
for i:=1 to m do
begin
readln(left,right,find);
sum:=0;
for j:=1 to n do
if (a[j].num>=left)and(a[j].num<=right) then
begin
inc(sum);
if sum=find then
begin
writeln(a[j].data);
break;
end;
end;
end;
end;
begin
init;
main;
endit;
end.