1001 : A Simple Problem

该博客介绍了一种算法问题,即在一个整数数列中找到最多有多少个连续子序列,使得这些子序列的最大值和最小值之差不超过K。通过实现单调队列来高效地处理这个问题,博主提供了AC代码并给出了样例输入和输出。文章重点讨论了算法思路和代码实现细节。
摘要由CSDN通过智能技术生成

题目: https://cpc.csgrandeur.cn/csgoj/problemset/problem?pid=1001

Description
在一个由N个整数组成的数列中,最多能找到多少个位置连续的整数且其中的最大值与最小值之差不超过K呢?

Input
输入包含若干组数据。每组数据的第一行有2个正整数,N(1<=N<=106),K(0<=K<=106),其中N、K的含义同上,接下来一行一共有N个32位有符号整数(32-bit signed integer),依次描绘了这个数列中各个整数的值。

Output
对于每组数据,输出一个正整数,表示在这个数列中最多能找到多少个位置连续的整数且其中的最大值与最小值之差不超过K。

Sample Input
4 2
3 1 5 2

3 2
3 1 2
Sample Output
2
3

思路:
通过单调队列去找最大值和最小值之差不小于k的连续整数

AC代码:

#include <iostream>
#include <stdio.h>
#include <queue>
#include <cmath>
using namespace std; 

const int maxn = int(1e6) + 10;

int q1[maxn],q2[maxn];
int a[maxn];
inline int cmp(int x,int y,int k){
	
	long long cx = x,cy = y,ck = k;
	if(abs(cx - cy) <= ck) return 1;
	else	return 0;
			
}

int main(){
	
	int n,k;
	
	while(~scanf("%d%d",&n,&k)){
		
		int ans = 1;
		
		int front1 = 0,front2 = 0,rear1 = 1,rear2 = 1;
		for(int i = 1;i<=n;i++)	scanf("%d",&a[i]);
		
		int i = 1,j = 1;
		q1[0] = q2[0] = 1; //将第一个元素下标进队
		 
		while(j < n){
			
			while(j < n && cmp(a[q1[front1]], a[q2[front2]], k)){
				
				j++;
				
				while(front1 < rear1 && a[j] <= a[q1[rear1-1]]) rear1--;
				q1[rear1++] = j;
				while(front2 < rear2 && a[j] >= a[q2[rear2-1]]) rear2--;
				q2[rear2++] = j;
			} 
			
			int len = j - i;
			if(j == n && cmp(a[q1[front1]], a[q2[front2]], k)) len++;
			ans = max(ans,len);
			
			if(a[q1[front1]] == a[j]){
				
				while(front1 < rear1 && !cmp(a[q1[front1]],a[q2[front2]], k)) front2++;
				i = q2[front2 - 1] + 1;
			}
			else if(a[q2[front2]] == a[j]){
				
				while(front2 < rear2 && !cmp(a[q2[front2]], a[q1[front1]], k)) front1++;
				i = q1[front1 - 1] + 1;
			}
			
		}
		
		printf("%d\n",ans);
	}
	
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值