首页 > 其他分享 >队列练习题

队列练习题

时间:2023-12-28 21:35:24浏览次数:31  
标签:练习题 洛谷 前缀 队列 back int 解题 序列

求m区间内的最小值(洛谷P1440)


题目大意

对一序列a,从左至右扫描,取每个位置前m个数的最小值,位置为首位置时输出0,不足m个数时就取这段范围内的最小值。


解题思路

使用单调队列,保持队头存最小元素下标,从队尾更新最值,超出窗口范围时队头出队。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
int q[N],a[N],head=1,rear=0,n,m;
int main(){
    scanf("%d %d",&n,&m);	//使用STL容器和cin,cout会超时
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	printf("0\n");
	for(int i=1;i<n;i++){
		while(head<=rear&&a[q[rear]]>a[i])rear--;
		q[++rear]=i;
		while(head<=rear&&q[head]<=i-m)head++;
		printf("%d\n",a[q[head]]);
	}
	return 0;
}

扫描(洛谷P2032)


题目大意

对于序列a,用一个长度为k的窗口从左至右按一单位滑动,求出每次滑动后窗口中的最大值。


解题思路

与上一题同类,换为队头存最大值即可。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+5;
int a[N],q[N],head=1,tail=0,n,m;
int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=n;i++){
        while(head<=tail&&a[q[tail]]<a[i])tail--;
        q[++tail]=i;
        if(i>=m){
            while(head<=tail&&q[head]<=i-m)head++;
            printf("%d\n",a[q[head]]);
        }
    }
    return 0;
}

切蛋糕(洛谷P1714)


题目大意

对于序列a,求连续最大个数不超过m的子序列和的最大值,序列值为整数。


解题思路

维护序列前缀和,对前缀和序列使用单调队列求最值。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int a,sum[N],n,m,ans=-0x3f3f3f3f;
deque<int>q;
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a;
		sum[i]=sum[i-1]+a;
	}
	q.push_back(0); //为求前缀和需要一个初值0
	for(int i=1;i<=n;i++){
		while(!q.empty()&&q.front()<i-m)q.pop_front();
		ans=max(ans,sum[i]-sum[q.front()]);
		while(!q.empty()&&sum[q.back()]>=sum[i])q.pop_back();
		q.push_back(i);
	}
	cout<<ans<<endl;
	return 0;
}

好消息,坏消息(洛谷P2629)


题目大意

对于序列a,可以进行转动,即\(a_1\) \(a_2\) \(\cdots\) \(a_{n-1}\) \(a_n\) -> \(a_k\) \(a_{k+1}\) \(\cdots\) \(a_n\) \(a_1\) \(a_2\) \(\cdots\) \(a_{k-1}\)
求有多少种k使得序列a的前缀和始终不小于0。


解题思路

维护序列前缀和,对前缀和序列使用单调队列求最值。

未知的代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int a[N<<1],s[N<<1],ans[N<<1];
int main(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		a[n+i]=a[i];
		s[i]=s[i-1]+a[i];
	}
	for(int i=n+1;i<=2*n-1;i++)s[i]=s[i-1]+a[i];    //将数组复制一份拼接可计算出题意需要的全部前缀和
	deque<int>q;
	for(int i=1;i<=2*n-1;i++){
		while(!q.empty()&&s[i]<s[q.back()])q.pop_back();
		q.push_back(i);
		while(!q.empty()&&q.front()<i-n)q.pop_front();
		if(i>=n)ans[i]=s[q.front()]-s[i-n]; //注意前缀和的计算
	}
	int cnt=0;
	for(int i=n;i<=2*n-1;i++){
		if(ans[i]>=0)cnt++;
	}
	cout<<cnt<<endl;
	return 0;
}

良好的感觉(洛谷P2422)


题目大意

对于序列a,求出一段子序列中的最小值与子序列元素之和的乘积的最大值。


解题思路

使用单调队列(实为单调栈)维护对应最小值的极大前缀和区间,用以计算最值并更新。

未知的代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+5;
int a[N],s[N];
deque<int>q;
signed main()
{
	int n;
	cin>>n;
	for(int i=1; i<=n; ++i){
	    cin>>a[i];
	    s[i]=s[i-1]+a[i];
	}
	int ans = 0;
	for(int i=1; i<=n+1; ++i)
	{
		while(!q.empty() && a[q.back()]>a[i])
		{
			int idx=q.back();
			q.pop_back();
			int left=q.empty()?0:q.back();
		    ans=max(ans,(s[i-1]-s[left])*a[idx]);//保证所更新区间为极大区间
		}
		q.push_back(i);
	}
	cout<<ans<<endl;
	return 0;
}

跳房子(洛谷P3957)


题目大意


解题思路


琪露诺(洛谷P1725)


题目大意


解题思路


小组队列(洛谷P2776)


题目大意


解题思路

标签:练习题,洛谷,前缀,队列,back,int,解题,序列
From: https://www.cnblogs.com/eternal-world/p/17926752.html

相关文章

  • k8s限速队列不通过Get方法判断队列是否关闭
    go.modmoduleuse-k8s-queuego1.19requirek8s.io/client-gov0.28.2require( github.com/go-logr/logrv1.2.4//indirect golang.org/x/timev0.3.0//indirect k8s.io/apimachineryv0.28.2//indirect k8s.io/klog/v2v2.100.1//indirect k8s.io/utils......
  • Python消息队列之Huey
    缘起:之前在Python中使用最多的就是Celery,同样的在这次项目中使用了Celery+eventlet的方式,但是由于具体执行的逻辑是使用的异步编写的,当时就出现了一个问题,当使用httpx的AsyncClient发送一个网络请求的时候,发生了阻塞,导致整个程序无法完整执行.于是就找替代方案,于是......
  • 栈练习题
    单调栈(洛谷P5788)题目大意与栈中的向右看齐相同题解未知的代码#include<bits/stdc++.h>usingnamespacestd;constintN=3e6+5;inta[N],ans[N],n;stack<int>s;intmain(){cin>>n;for(inti=1;i<=n;i++)cin>>a[i];for(inti=n;i>=1;i--){......
  • P1339 [USACO09OCT] Heat Wave G 最短路入门题 Dijkstra/SPFA/Dijkstra+优先队列优化
    目录朴素的Dijkstra算法SPFA算法Dijkstra+优先队列优化题目链接:https://www.luogu.com.cn/problem/P1339题目大意:无向图有单源最短路。朴素的Dijkstra算法时间复杂度\(O(n^2)\)。#include<bits/stdc++.h>usingnamespacestd;constintmaxn=2505;structEdge......
  • rabbitMq怎么查看队列日志消息-Tracing日志
    Trace是Rabbitmq用于记录每一次发送的消息,方便使用Rabbitmq的开发者调试、排错。1、启动Tracing插件在RabbitMQ中默认是关闭的,需手动开启。此处rabbitMQ是使用docker部署的##进入rabbitMq中dockerexec-itrabbitmq1bash##启动日志插件rabbitmq-pluginsenablerabbitmq_tr......
  • Java多线程​(五)练习题7道
    练习多线程练习1(卖电影票)一共有1000张电影票,可以在两个窗口领取,假设每次领取的时间为3000毫秒,要求:请用多线程模拟卖票过程并打印剩余电影票的数量线程类实现:publicclassTicketWindowextendsThread{publicTicketWindow(){}publicTicketWindow(Stringname){super(nam......
  • [刷题技巧] 栈和队列相关知识点汇总
    栈主要考察单调栈,队列主要考察优先队列(堆)。栈和队列(ArrayDeque)数据结构ArrayDeque类是双端队列Deque接口的实现类。Deque的含义是"doubleendedqueue",即双端队列,它既可以当作栈使用,性能优于Stack,也可以当作队列使用,性能优于LinkedList。ArrayDeque和LinkedList是Dequ......
  • 代码随想录算法训练营第十天 | 栈与队列理论基础,232.用栈实现队列,225.用队列实现栈
    一、栈与队列理论基础学习:1.定义栈先进后出队列先进先出2.底层实现均可以通过数组或链表进行实现二、232.用栈实现队列题目链接:LeetCode232.用栈实现队列学习前:思路:无学习后:不同方法有部分功能实现是一致的,则可以进行抽象提取,实现复用性两个栈实现队列时......
  • 队列
    机器翻译(洛谷P1540)题目大意有m个可存放单词和译意的单元,初始内容为空,依次读取文章单词,若在内存单元中不存在则从外存读入,载入内存,若内存数据超过m则最先录入内存单元的出队,直到文章全部翻译完,求外存查找次数。解题思路限定了队列容量为m,每当队列中找不到匹配单词时从外存载......
  • 消息队列(一)
    消息队列是做什么的?消息队列(MessageQueue,简称MQ)是一种在消息的传输过程中保存消息的容器。它是一种跨进程或线程间通信的方式,常用于不同进程或线程间异步处理数据。消息队列利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。消息队列一......