队列问题非STL解决方案
队列问题非STL解决方案
常年使用STL解决队列问题,以至于严重生疏队列的根本原理。。。
直到今日 被老师被迫 使用算法原理解决问题,方才意识到我对队列一窍不通。。。
。。。直到 经过一系列的坑蒙拐骗 之后,方才理清楚一些头绪,在此附记。
有关概念在此不再赘述,因为这东西怕不是一搜一大堆。。。
循环队列——数组存储方案:
我们需要的东西:
1.一个数组,拿来存队列。
int ique[capa];//capa是数组(队列)的最大容量,看下面↓
2.头指针及尾指针,指明队列的头和尾。
int ihead=0,itail=0;
3.再来两个量——队列的当前长度(是变量)及其最大容量(是常量,在开数组时已经界定,这里为演示开的短一些,只开到4)
int ilen=0;
const int capa=4;
接下来是一些基本的操作:
1.将elem入队:
int elem;
ique[itail]=elem;//尾指针始终指向队列尾部的下一个位置,因此我们只需将尾指针处的数字做出更改即可。
itail++;//尾指针自增,指向下一个位置。
itail=itail % capa;//圈重点,见下↓
ilen++;//因为多了一个元素而长度增加,使ilen自增。
itail=itail % capa;
我们一直在使尾指针自增,而数组的长度只有4。 在这里通过取余即可实现循环入队。这样当尾指针增大到capa以外时,通过该语句即可自动使尾指针跳转回数组的开头,实现循环读入、循环存储。
在这里尾指针始终指向队列尾部的下一个位置,使其指向队列尾部那个元素的原理是相同的。
2.出队,存入elem:
int elem;
elem=ique[ihead];//直接取出头指针处的元素
ihead++;//头指针往下移动
ihead=ihead % capa;//和上面同理
ilen--;//因为少了一个元素而长度减少,使ilen自减。
比较关键的操作就在于将指针对capa取余,这样的操作可以使指针形成循环,也就实现了队列的循环存储。在其他地方如果我们需要用到循环存储,对其容量取余是个很好的思路。当然实际应用中其大小不仅仅是4这么少,我们还应该留意数据范围合理安排空间,要不出现了塞不下或者空太多的问题都是很辣手棘手的。
基本的操作就是这样 (是不是很简单) (是不是理解起来有些难) (还是本来就挺简单被我给说难了。。。)
举个例子:
洛谷P1996 约瑟夫问题
题目:
n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.
输入格式
n m
输出格式
出圈的编号
输入样例
10 3
输出样例
3 6 9 2 7 1 8 5 10 4
说明
m,n≤100
-->用STL的话基本不用动脑,5分钟搞定。如下:
#include<queue>//队列所必须的头文件
#include<cstdio>
using namespace std;
queue <int> set;//创建该队列
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
set.push(i);//把各个人的编号入队准备报数
}
int counti=1;//报数的计数器
while(!set.empty())
{
if(counti!=m)
{
set.push(set.front());//不是m,循环将队头塞进队尾,实现循环
set.pop();
}
if(counti==m)
{
printf("%d ",set.front());//是m这个人出列,将其编号输出后出队
set.pop();
counti=1;//再次从1开始
continue;//继续
}
counti++;
}
return 0;
}
不使用STL的话,构建队列就要稍微麻烦一些,不过能更好的理解其原理及应用。然而无论如何STL都只是个工具,我们必要应该掌握的还是其实现原理。下面是无STL的解决方案:
//luogu.org P1996 -- NO STL Solution
//queue--Array Solution
//IZWB003-2019/07/24
#include<cstdio>
//set queue//设置该队列
int head=0,tail=0;//指针2个
int length=0;const int capacity=120;//大小及长度
int queue[capacity];//通过数组储存队列
int element;
using namespace std;
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
queue[tail]=i+1;//尾指针处入队
tail++;
tail=tail%capacity;//上面的方法
length++;//改长度
}
int i=0;//以i作为报数的计数器
while(true)
{
element=queue[head];//头指针处出队
head++;
head=head%capacity;//上面的方法
length--;//改长度
i++;//报数
if(i==m)//该出队处
{
printf("%d ",element);//输出
i=0;//重新报数
}
else//不符合则接着入队
{
queue[tail]=element;
tail++;
tail=tail%capacity;
length++;
}
if(length==0) break;//队空则结束
}
return 0;
}
有关链表建队列的相关知识,有时间的话,稍后补充。
队列问题非STL解决方案的更多相关文章
- 标准非STL容器 : bitset
1. 概念 什么是"标准非STL容器"?标准非STL容器是指"可以认为它们是容器,但是他们并不满足STL容器的所有要求".前文提到的容器适配器stack.que ...
- 探讨SQL Server并发处理队列数据不阻塞解决方案
前言 之前对于并发这一块确实接触的比较少,自从遇到现在的老大,每写完一块老大都会过目一下然后给出意见,期间确实收获不少,接下来有几篇会来讲解SQL Server中关于并发这一块的内容,有的是总结,有的 ...
- java阻塞队列与非阻塞队列
在并发编程中,有时候需要使用线程安全的队列.如果要实现一个线程安全的队列有两种方式:一种是使用阻塞算法,另一种是使用非阻塞算法. //使用阻塞算法的队列可以用一个锁(入队和出队用同一把锁)或两个锁(入 ...
- 蓝桥 ADV-233 算法提高 队列操作 【STL】
算法提高 队列操作 时间限制:1.0s 内存限制:256.0MB 问题描述 队列操作题.根据输入的操作命令,操作队列(1)入队.(2)出队并输出.(3)计算队中元素个数并输出. ...
- Windows消息理解(系统消息队列,进程消息队列,非队列消息)
// ====================Windows消息分类==========================在Windows中,消息分为以下三类:标准消息——除WM_COMMAND之外,所 ...
- HDU 4280Island Transport(Dinc非STL 模板)
题意: n岛m条路,然后是 n个岛的坐标,然后是m条双向路,包括 岛和 岛 之间 最大客流量,让求 最左边的岛 到右边的岛 最大客流量 分析: 建图 以 左边的岛为原点,最右边的为终点求最大客流量. ...
- calc 多项式计算 (STL版和非STL版) -SilverN
计算(calc.cpp) [问题描述] 小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)”,“0-9”,“+”,“-”,“*” ...
- 栈和队列简单的STL模板
栈的使用,可以想象成是只有一个出口,最后进来的那个最先出去: #include <stack> 队列:是有两个出口,但是进来了之后只能从前门出去,也就是最先进来的那个最后出去: #incl ...
- win10每次开机都会自检系统盘(非硬件故障)——解决方案2019.07.12
1.最近反复遇到了这个问题,之前遇到这个问题就把系统重装了,没想到今天又遇到了,目前系统东西太多了,重装太麻烦了,就下决心解决一下. 2.不要使用网络上流传的修改注册表的方案,把注册表的那个键值删除那 ...
随机推荐
- [Codeforces 1205B]Shortest Cycle(最小环)
[Codeforces 1205B]Shortest Cycle(最小环) 题面 给出n个正整数\(a_i\),若\(a_i \& a_j \neq 0\),则连边\((i,j)\)(注意i- ...
- 在eclipse上配置多个jdk
在实际生产中,可能会遇到这样的问题:在eclipse中存在多个项目时,可能不同的项目需要不同的jdk版本.这时,我们就可以给eclipse配置多个jdk进行切换. 注:貌似只有较新版eclipse才能 ...
- 1705. [Usaco2007 Nov]Telephone Wire 架设电话线
传送门 显然 $dp$,首先设 $f[i][j]$ 表示当前考虑到第 $i$ 个电线杆,高度为 $j$ 时的最小代价 那么有转移 $f[i][j]=f[i-1][k]+cost+C(j-k)$,其中 ...
- moongoose对象无法新增删除属性
昨天用nodes中的moongoose去查询一个结果遇到一个大坑,这个坑貌似用moongoose可能会遇到.背景是这样的,我在nodejs中去查询document,得到的可以看作是一个对象list.在 ...
- 一、苹果Assets.car文件解析图片
一. https://blog.wxhbts.com/assets.html
- window 批处理脚本获取上级目录
1 SET CurrDir=%CD% CD.. SET InstPath=%CD% CD %CurrDir% 2 pushd.. set parent=%cd% popd 参考: https://ms ...
- 2018-09-10-weekly
Algorithm 删除链表的倒数第N个节点 What:给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点. How:这是一道典型的利用双指针法解题.首先让指针first指向头节点,然后 ...
- 多组件共享-vuex
1.解决多个组件共享同一状态数据问题1)多个视图共享同一状态2)来自不同视图的触发事件需要变更同一状态文档API:https://vuex.vuejs.org/zh/api/ 2.组件与store连接 ...
- DELPHI FMX 获取系统版本 ANDROID IOS通用
引用System.sysutils function getOSInfo:String; begin result:= fomrat('%s:%d.%d', TOSVersion.Name,TOSVe ...
- java匿名内部类 (转载)
匿名内部类也就是没有名字的内部类 正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写 但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口 实例1:不使用匿名内部类来实现抽象 ...