1542:【例 2】最敏捷的机器人

【题目描述】
Wind 设计了很多机器人。但是它们都认为自己是最强的,于是,一场比赛开始了……

机器人们都想知道谁是最敏捷的,于是它们进行了如下一个比赛。首先,他们面前会有一排共 n 个数,它们比赛看谁能最先把每连续 k 个数中最大和最小值写下来,当然,这些机器人运算速度都很快,它们比赛的是谁写得快。

但是 Wind 也想知道答案,你能帮助他吗?

【输入】
第一行为 n,k,意义如题目描述。

第二行共 n 个数,为数字序列,所有数字均在 Pascal 的 longint 范围内,即所有数均为整数,且在 [−231,231−1]范围内。

【输出】
共 n−k+1 行,第 i 行为第 i 至第 i+k−1 这 k 个数中的最大和最小值。

【输入样例】
5 3
1 2 3 4 5
【输出样例】
3 1
4 2
5 3
【提示】
数据范围与提示:

对于全部数据,1≤k≤n≤105 。

【来源】

st表模板题,比昨天写的快多了,理解加深了一点,但还是有些地方卡壳,这题就比昨天多了一个记录Min的数组,还有理解位运算符和st表的存储过程时理解st表的关键

#include<iostream>
#include<cstdio>
#include<cmath>
const int N = 1e5+5;
using namespace std;
int n,k,f[N][25],f1[N][25],a[N],Log[N];
//预处理
void init(){
	Log[1] = 0; 
	for(int i=2;i<=n+1;i++) Log[i] = Log[i/2] + 1;
	for(int i=1;i<=n;i++) {
		f[i][0] = f1[i][0] = a[i];
	}
	for(int j=1;(1<<j) <=n;j++){
		for(int i=1;i+(1<<j-1) <=n;i++){
			f[i][j] = max(f[i][j-1] , f[i+(1<<j-1)][j-1]);
			f1[i][j] = min(f1[i][j-1] , f1[i+(1<<j-1)][j-1]);
		}
	}	
} 
int ansmax(int l,int r){
	int k=Log[r-l+1];
	return max(f[l][k] , f[r-(1<<k)+1][k]);
}
int ansmin(int l,int r){
	int k=Log[r-l+1];
	return min(f1[l][k] , f1[r-(1<<k)+1][k]);
}
int main(){
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n;i++) scanf("%d",a+i);
	init();
	for(int i=1;i<=n-k+1;i++){
		printf("%d %d\n",ansmax(i,i+k-1),ansmin(i,i+k-1));
	}
	return 0;
}
发布了139 篇原创文章 · 获赞 3 · 访问量 8503

猜你喜欢

转载自blog.csdn.net/weixin_44270812/article/details/103063804