【區間最值】、sequence

【區間最值】、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.

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章