The Water Problem
Time Limit: 1500/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Problem Description
In Land waterless, water is a very limited resource. People always fight for the biggest source of water. Given a sequence of water sources with
a1,a2,a3,...,an
representing the size of the water source. Given a set of queries each containing
2
integers
l
and
r
, please find out the biggest water source between
al
and
ar
.
Input
First you are given an integer
T(T≤10)
indicating the number of test cases. For each test case, there is a number
n(0≤n≤1000)
on a line representing the number of water sources.
n
integers follow, respectively
a1,a2,a3,...,an
, and each integer is in
{1,...,106}
. On the next line, there is a number
q(0≤q≤1000)
representing the number of queries. After that, there will be
q
lines with two integers
l
and
r(1≤l≤r≤n)
indicating the range of which you should find out the biggest water source.
Output
For each query, output an integer representing the size of the biggest water source.
Sample Input
3 1 100 1 1 1 5 1 2 3 4 5 5 1 2 1 3 2 4 3 4 3 5 3 1 999999 1 4 1 1 1 2 2 3 3 3
Sample Output
100 2 3 4 4 5 1 999999 999999 1
Source
题意:给你一个n个元素的序列,q次询问,每次询问让你找出区间[li,ri]中的最大值
解题思路:因为此题的数据规模比较小,一般想到的方法都是可以的,比如暴力呀、线段树呀,虽然一道水题没必要浪费时间写一个线段树,但在这里,我会把目前想到的这两种方法都讲一下①首先是暴力的做法,这种做法想法比较简单,对于每次询问,直接遍历区间[li,ri]找出最大值就可以了
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<stdlib.h>
#include<cmath>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 1005;
const int inf = 1000000000;
const int mod = 2009;
int s[N];
int main()
{
int t,n,i,j,q,l,r,Max;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&s[i]);
scanf("%d",&q);
for(i=0;i<q;i++)
{
scanf("%d%d",&l,&r);
for(Max=0,j=l;j<=r;j++)
Max=Max>s[j]?Max:s[j];
printf("%d\n",Max);
}
}
return 0;
}
②利用线段树,保留每个区间的最大值,这样对于每次询问,我们只需O(logn)的复杂度遍历线段树,找到最大值
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<deque>
#include<cmath>
#include<functional>
#include<iterator>
#include<set>
#include<utility>
#include<stack>
#include<queue>
#include<iostream>
using namespace std;
#define maxn 11000
#define mod 1000000007
int a[maxn];
struct node
{
int l,r,ma;
}tree[maxn*4];
void build(int l,int r,int p)
{
tree[p].l = l;
tree[p].r = r;
tree[p].ma = -1;
if(l == r)
{
tree[p].ma = a[l];
return;
}
int mid = (l+r)/2;
build(l,mid,p*2);
build(mid+1,r,p*2+1);
tree[p].ma = max(tree[p*2].ma,tree[p*2+1].ma);
}
int query(int x,int y,int p)
{
if(x == tree[p].l && y == tree[p].r)
return tree[p].ma;
int mid = (tree[p].l + tree[p].r)/2;
if(x > mid)
return query(x,y,p*2+1);
else if(y <= mid)
return query(x,y,p*2);
else
return max(query(x,mid,p*2),query(mid+1,y,p*2+1));
}
int main()
{
int T,i,j,k,n,q,x,y;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
for(i=1;i<=n;++i)
scanf("%d",&a[i]);
build(1,n,1);
scanf("%d",&q);
for(i=1;i<=q;++i)
{
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y,1));
}
}
return 0;
}
菜鸟成长记

本文讨论了在一个水资源稀缺的世界中,如何通过给定的水源大小序列和查询范围,找出最大水源的问题。文中提供了两种解决方案:一种是暴力搜索方法,通过遍历指定区间内的所有水源来找到最大的水源;另一种是利用线段树结构,预先存储每个区间的最大水源,从而在每次查询时以较低的时间复杂度找到答案。此外,文章还强调了数据结构在解决实际问题中的重要性。

被折叠的 条评论
为什么被折叠?



