基准时间限制:1 秒 空间限制:131072 KB 分值: 0
难度:基础题
给出一个有N个数的序列,编号0 - N - 1。进行Q次查询,查询编号i至j的所有数中,最大的数是多少。
例如: 1 7 6 3 1。i = 1, j = 3,对应的数为7 6 3,最大的数为7。(该问题也被称为RMQ问题)
Input
第1行:1个数N,表示序列的长度。(2 <= N <= 10000) 第2 - N + 1行:每行1个数,对应序列中的元素。(0 <= S[i] <= 10^9) 第N + 2行:1个数Q,表示查询的数量。(2 <= Q <= 10000) 第N + 3 - N + Q + 2行:每行2个数,对应查询的起始编号i和结束编号j。(0 <= i <= j <= N - 1)
Output
共Q行,对应每一个查询区间的最大值。
Input示例
5 1 7 6 3 1 3 0 1 1 3 3 4
Output示例
7 7 3
本着学习线段树的运用,没想到动态规划水过~~~
#include <stdio.h>
#include <string.h>
#define MAXN 100010
int num[MAXN];
int max( int a , int b ){
return a>b?a:b;
}
//传入起点和终点
int dp( int start , int end ){
//区间头尾相等了,就只有一个元素了,返回
if( start==end )
return num[start];
//分两段
int mid = ( start+end )/2;
//分两段,分别取最大值,然后比较取最大的
return max( dp( start,mid ),dp( mid+1,end ) );
}
int main(){
freopen( "input.txt","r",stdin );
int n,m;
scanf( "%d",&n );
for( int i=0 ; i<n ; i++ )
scanf( "%d",&num[i] );
scanf( "%d",&m );
int s,e;
while( m-- ){
scanf( "%d%d",&s,&e ) ;
printf( "%d\n",dp( s,e ) );
}
}
然后是线段树的运用~~
#include <stdio.h>
#include <string.h>
#define MAXN 10010
#define max(x,y) ((x)>(y)?(x):(y))
int data[MAXN];
int segTree[MAXN*3];
//建立线段树(传递当前位置即当前区间的参数)
void build( int pos , int start , int end ){
//如果区间重合为一个点,线段树节点的值为这个点的值
if( start==end )
segTree[pos] = data[start];
else{
int mid = ( start+end )/2;
//建立左子树
build( 2*pos , start , mid );
//建立右子树
build( 2*pos+1 , mid+1 , end );
//线段树的值为左右子树中值较大的
segTree[pos] = segTree[ 2*pos ] > segTree[ 2*pos+1 ] ? segTree[ 2*pos ] : segTree[ 2*pos+1 ];
}
}
//查询,传入当前位置,当前位置包含的区间,目标区间
int query( int pos , int start , int end , int left , int right ){
if( left<=start && right>=end )
return segTree[pos];
int mid = ( start+end )/2;
// printf( "pos=%d\tstart=%d\tend=%d\tleft=%d\tright=%d\n",pos,start,end,left,right );
long long ans = -1;
if( left<=mid )
ans = max( ans,query( pos*2,start,mid,left,right ) );
if( right>mid )
ans = max( ans,query( pos*2+1,mid+1,end,left,right ) );
return ans;
}
int main(){
int n,m;
freopen( "input.txt","r",stdin );
while( ~scanf( "%d",&n ) ){
memset( segTree,0,sizeof(segTree) );
for( int i=0 ; i<n ; i++ )
scanf( "%d",&data[i] );
build( 1,0,n-1 );
int s,e;
scanf( "%d",&m );
while( m-- ){
scanf( "%d%d",&s,&e );
printf( "%lld\n",query( 1,0,n-1,s,e ) );
}
}
}
okok,溜了溜了~~~