【区间最值】、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.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值