数据结构作业保存3-5返回指定区间内的最大值

我第一次写时,不知道有RMQ这个神奇又好用的算法。自己敲了一个,交上去。。。超内存不过,而且因为思路原因要重敲。

这时候请教同学才知道RMQ!我真是太朴实了。

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Input
第一行一个t(1<=t<=100),代表有t组数据,接下来t组数据,每组数据第一行首先输入两个数n,m(1<=n<=100000), 代表有n个数, m的含义见描述,接下来一行输入n个数,代表a[1],a[2],...a[n]的值


Output
 对于每组数据输出n-m+1行,第i行代表MAX(a[i],a[i+1],...,a[i+m-1])


Sample Input
2
10 3
3 1 2 -2 1 3 7 21 0 9
5 1
2 1 3 5 4
Sample Output
3
2
2
3
7
21
21
21
2
1
3
5
4

</pre><p>---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------</p><p><pre name="code" class="cpp">#include <iostream>  
#include <stack>  
#include <queue>  
#include<cmath>
#include <algorithm>  
#include <cstring>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype> 
#include <malloc.h>
#include <stdlib.h>
using namespace std;

queue<int>out;
int a[100001];
int mx[100001][100]; //后面开100就够了,开多了就算你内存超了。。。 
int n,m,t;

int ASK(int L,int R){
	int y=(int)(log(R-L+1)/log(2));
	return max(mx[L][y],mx[R-(1<<y)+1][y]);
}
void RMQ(){
	int i,j;
	for(i=1;i<=n;i++)//初始化 
		mx[i][0]=a[i];
	for(j=1;j<=int(log(n)/log(2));j++)
		for(i=1;i+(1<<j)-1<=n;i++)
			mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]);
} 
int main(){
	scanf("%d",&t);
	for(int k=1;k<=t;k++){
		scanf("%d %d",&n,&m);
		for(int r=1;r<=n;r++)
			scanf("%d",&a[r]);
	RMQ();
	for(int s=1;s<=n-m+1;s++)
		out.push(ASK(s,s+m-1));
	memset(a,0,sizeof(int));
	}
		while(!out.empty()){
		printf("%d\n",out.front());
		out.pop();
	}
	return 0;
}
------------------------------------------------------------------------还要我超内存的朴实代码------------------------------------------------------------------------------------------------------------------------------
#include <iostream>  
#include <stack>  
#include <queue>  
#include <algorithm>  
#include <cstring>  
#include <cstdio>  
#include <cstdlib>  
#include <cctype> 
#include <malloc.h>
#include <stdlib.h>
using namespace std;

int max(int n,int m,int k,queue<int>in){
	int temp;
	queue<int>incopy=in;
	for(int n=1;n<k;n++)
		incopy.pop();
	temp=incopy.front();
	for(int i=k;i<=k+m-1;i++){
		if(temp<incopy.front())
			temp=incopy.front();
		incopy.pop();
	}
	while(!incopy.empty())
		incopy.pop();
	return temp;
}
int main(){
	int t;
	int n,m;
	queue<int>out;
	queue<int>in;
	int t1;
	scanf("%d",&t);
	for(int s=0;s<t;s++){
		scanf("%ld %ld",&n,&m);
		for(int j=0;j<n;j++){ //输入一组数据 
			scanf("%d",&t1);
			in.push(t1); 	
		}
		
		for(int k=1;k<=n-m+1;k++){		//把第K行的最大值找出来 
			out.push(max(n,m,k,in));
		}
		while(!in.empty())
			in.pop();
		
	}
	while(!out.empty()){
		printf("%d\n",out.front());
		out.pop();
	}
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值