大一寒假培训(七)——队列与优先队列
文章目录
- 队列的定义
- 队列的基本操作
- 周末舞会
- 取纸牌游戏
- 海港(NOIP2016普及组真题)
- Blash数集-队列-set
- 优先队列
- 优先队列的定义
- 优先队列的定义方法
- 用结构体定义优先队列(重载函数)
- 合并果子-优先队列
- 桐桐的新闻系统-优先队列
- 序列合并-优先队列
疫情影响,导致我们宅在家里无(feng)所(kuang)事(bu)事(fan),但是一条消息终止了我们的行为
于是我们又迎来了一轮培训。
首先花了两天时间学习了队列和优先队列,并且做了相应的习题。
队列的定义
队列就是允许在一端进行插入,在另一端进行删 除的线性表。允许插入的一端称为队尾,通常用一个 队尾指针r指向队尾元素,即r总是指向最后被插入的 元素;允许删除的一端称为队首,通常也用一个队首 指针f指向排头元素的前面。初始时f=r=0。
队列的基本操作
(1)初始化队列 queuevis,定义一个队列
(2)入队 vis.push(x)
(3)出队 vis.pop()
(4)判断队列是否为空 vis.empty()
(5)判断队列中元素的数量vis.size()
(6)得到队列的队首元素 vis.front()
综上: #include
用<bits/stdc++.h>则无需考虑头文件。
那么先来一道简单的例题。
周末舞会
分析:设计两个队列分别存放男士和女士。每对跳舞 的人一旦跳完后就回到队尾等待下次被选。
queue<int>vis1,vis2;
int main()
{int n,m,k,s1,s2;cin>>n>>m;cin>>k;for(int i=1;i<=n;i++) vis1.push(i);for(int i=1;i<=m;i++) vis2.push(i);for(int i=1;i<=k;i++){ s1=vis1.front(); vis1.pop(); vis1.push(s1); //取出对首,并将其放在队尾s2=vis2.front(); vis2.pop(); vis2.push(s2); //同上cout<<s1<<" "<<s2<<endl;}
const int maxn=1000;
int queue[maxn],counter=0,front=0,back=-1 ;
void push(int x)
{queue[++back]=x;++counter;}
int pop()
{--counter; return queue[front++];}
取纸牌游戏
解题思路:
发现“good”的牌都发给了小明自己,根据题目描述的N的倍数都发給了小明自己,所以当K 是N的倍数时,就存入到一个数组当中去。对于这个P要格外注意,当剩余的牌的个数小于P的时候也要 P次。
例如: p=3;
还剩下的编号为4和5;
第1次翻:5 4;
第2次翻:4 5;
第3次翻:5 4;
也是要翻3次的,哪怕就省下1张牌了,也要翻P次!
#include <bits/stdc++.h>
using namespace std;
int a[100005];
queue<int>vis;
int main()
{int n,k,p,num=0,z=0;cin>>n>>k>>p;for(int i=1;i<=k;i++)vis.push(i);while(!vis.empty()){int tmp=vis.front();vis.pop();num++;if(!(num%n)) //如果是n的倍数,则计数a[z++]=tmp;if(!vis.empty())for(int i=0;i<p;i++){ //移动p次牌tmp=vis.front();vis.pop();vis.push(tmp);}}sort(a,a+k/n);for(int i=0;i<k/n;i++)cout<<a[i]<<endl;return 0;
}
海港(NOIP2016普及组真题)
考虑用队列就可以,把每个乘客都分别以结构体的形式即进 入队列(是每一个乘客),结构体{时间,国籍},然后使用 桶排序的思想记录就可以了, 也可以用map来代替桶排序! 当一艘船进入海港时,先压入队列(每个人); 然后在从队 列头开始检查是否满足条件(出栈时计算总的国籍数是否变 化)
struct sa {
int t;//进港时间
int x;//国家
};
本题的难点就在于如何存储本题的数据,把每个人分别入队列就解决了船的问题,有点不好想。
难点:num[x]是桶排序的数组,ans是国家的数量。
1、根据num[x]==0 来判断是增加或减少一个国家。
2、每次新来的船,都先入队列,并统计国家数。
3、用刚新来船的时间和队列头部的船只时间进行比较
4、时间大于等于86400,就出队列,并计算国家数。
5、输出当前的国家数。
#include <bits/stdc++.h>
using namespace std;
struct peo{int t;int x;
};
queue<peo>vis;
int n,t,k,x,ans=0;
int num[100005];
int main()
{ios::sync_with_stdio(0);struct peo tmp;cin>>n;for(int i=0;i<n;i++){cin>>t>>k;for(int j=0;j<k;j++){cin>>x;vis.push({t,x});if(!num[x]) ans++;num[x]++;}while(t-vis.front().t>=86400){tmp=vis.front();vis.pop();int x1=tmp.x;num[x1]--;if(!num[x1]) ans--;}cout<<ans<<endl;}return 0;
}
Blash数集-队列-set
#include <bits/stdc++.h>
using namespace std;
int a,n,m[1000005],t2,t3,t,jie;
int main()
{cin>>a>>n;m[1]=a;t2=t3=1;jie=2;while(jie<=n) //求取第n小的数{int x2,x3;x2=m[t2]*2+1; //2x+1在数集中x3=m[t3]*3+1; //3x+1在数集中t=min(x2,x3); //取x2,x3的较小值if(x2>x3) //哪一方较小,就下标+1t3++;elset2++;if(m[jie-1]!=t) //去重,如果t与前一个数相同,则不用放入数组m[jie++]=t;}cout<<m[n]<<endl;return 0;
}
这道题也可以使用set+queue做,set用来去重
优先队列
优先队列的定义
priority_queue翻译为优先队列,一般用来解决一些贪心问题,其底层是用“堆”来实现的。在优先队列中,任何时刻,队首元素一定是当前队列中优先级最高(优先值最大) 的那一个(大根堆),也可以是最小的那一个(小根堆)。 可以不断往优先队列中添加某个优先级的元素,也可以不断弹出优先级最高的那个元素,每次操作其会自动调整结构, 始终保证队首元素的优先级最高。
优先队列的定义方法
定义和使用priority_queue前,要添加queue头文件。
定义一个priority_queue的方法为: priority_queue< type > name;//type通常为结构体
其中,type可以是任何基本类型或者容器,name为优先队列的名字。
和queue不一样的是,priority_queue没有front()和back(),而只能通过top()或pop()访问队首元素(也称堆顶元素),也就是优先级最高的元素。
大根堆:从大到小排列。
小根堆:从小到大排列。
优先队列就是堆,也可以自己手写堆。
//小根堆的写法 priority_queue<int,vector< int >,greater< int > > vis;
//大根堆的写法 priority_queue<int,vector< int >,less< int > > vis;
当就是1个类型,可以这样直接写; 也可以用结构题
用结构体定义优先队列(重载函数)
typedef long long LL;
struct sa {
LL x;
LL y;
LL sum;
};
LL a[400005],b[400005];
bool operator < (const sa &a,const sa &b)
{
return a.sum >b.sum;//表示的是从小到大
}
合并果子-优先队列
分析:
每次取2个数出来,合并后的数再压入优先队列!
再用1个变量累加记录每次取2个数的和!
队列:1 2 9
1+2=3; 把3压入队列;ans+=3;
队列:3 9
3+9=12;
ans+=12; 答案=15;如果队列为空就不放元素了!
#include <bits/stdc++.h>
using namespace std;
int n,x,ans;
priority_queue<int,vector<int>,greater<int> >q;
int main()
{ios::sync_with_stdio(0);cin>>n;for(int i=0;i<n;i++) {cin>>x;q.push(x);}while(q.size()>1){int t1=q.top();q.pop();int t2=q.top();q.pop();q.push(t1+t2);ans+=t1+t2;}cout<<ans<<endl;return 0;
}
桐桐的新闻系统-优先队列
5
Sample Output
2004
2005
2004
2004
2005
构造一个结构体
struct node{
int num,tim,sum;
} ;
tim是间隔时间,sum是总共的时间
这样先把所有的用户输入,再进行排序
一个用户被弹出队列后,将sum+=tim后,在插进队列里
#include <bits/stdc++.h>
using namespace std;
struct node{int num,tim,sum;
} ;
char a[10];
bool operator < (const node &s1,const node &s2)
{if(s1.sum!=s2.sum) return s1.sum>s2.sum; //先按sum从小到大排序return s1.num>s2.num; //再按num从小到大排序
}
int num,tim,k;
priority_queue<node,vector<node> >q;
int main()
{node tmp;ios::sync_with_stdio(0);while(cin>>a,a[0]!='#'){cin>>num>>tim;tmp.num=num;tmp.tim=tim;tmp.sum=tim;q.push(tmp);}cin>>k;while(k--){tmp=q.top();q.pop();cout<<tmp.num<<endl; //输出numtmp.sum+=tmp.tim;q.push(tmp); //重新插入队列}return 0;
}
序列合并-优先队列
分析:
如果把n·n个数都算出来,一定会TLE
那么只能考察优化的方法,如何把前n个数放进去,也就是位置的先后入队列的顺序。
本题时间卡的很紧,用快读也没快多少,还是scanf()的好!
本题主要的思路,在纸上自己计算一下,先把第一行的和入优先队列, 然后从第2行的和开始,每出队列1个和就把这个位置下方的和压入队列!
例如坐标<1,1>的和出队列,就把坐标<2,1>的和压入队列
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=4e5+10;
int n,a[N],b[N];
struct node{int x,y;ll sum;
};
bool operator < (const node &s1,const node &s2)
{return s1.sum>s2.sum;}
priority_queue<node,vector<node> >q;
int main()
{ios::sync_with_stdio(0);node tmp;cin>>n;for(int i=0;i<n;i++) cin>>a[i];for(int i=0;i<n;i++) cin>>b[i];tmp.y=0;for(int i=0;i<n;i++) tmp.x=i,tmp.sum=a[i]+b[0],q.push(tmp);for(int i=0;i<n;i++){tmp=q.top();q.pop();printf("%lld\n",tmp.sum);tmp.y++;tmp.sum=a[tmp.x]+b[tmp.y];q.push(tmp);}return 0;
}
大一寒假培训(七)——队列与优先队列相关推荐
- 大一寒假培训(三)——暴力枚举及妙用
大一寒假培训(三) 经过两天的培训之后,第三天也到来了.今天讲的是暴力枚举.好像没什么可讲的(悄咪咪地说) 接下来还是今天的练习 nefu 8 二倍的问题 Description 给定2到15个不同的 ...
- 大一寒假培训(二)——快排与桶排
大一寒假培训(二) 今天是寒假培训的第二天,今天学了快排和桶排.以下是今天做的习题. nefu 1481 谁考了第k名-排序 Description 在一次考试中,每个学生的成绩都不相同,现知道了每个 ...
- NEFU 大一寒假培训【一】二维数组、结构体
主题:二维数组.结构体 A 二维矩阵对角线和 Description 计算m×m的方阵的对角线所有元素的和 Input 输入数据有多组,每组第1行为m (2<=m<=10),接下来有m行m ...
- 2020大一寒假培训三 (暴力)
比例简化 Problem:J Time Limit:1000ms Memory Limit:65535K Description 在社交媒体上,经常会看到针对某一个观点同意与否的民意调查以及结果.例如 ...
- 大一寒假训练:集训内容考试(二)【未完待续】
一.前情提要 在经过三天的摸鱼 学习写bug队列.优先队列和素数筛相关内容之后,参加集训的同学们终于迎来了第二场考试,在这场考试中,我会有哪些脑残操作进步呢? 总结: 1.用scanf多组输入再一次忘 ...
- java先进先出 循环队列,JavaScript队列、优先队列与循环队列
队列是一种遵从先进先出(FIFO)原则的有序集合 队列在尾部添加新元素,从顶部移除元素 队列的理解 队列在我们生活中最常见的场景就是排队了 队列这个名字也已经很通俗易懂了 和栈很像,这不过队列是先入先 ...
- NEFU 大一寒假训练十二(set)2020.02.18
Summary 可能是昨天的题少了一些,今天的题多了一堆,还疯狂TLE /(ㄒoㄒ)\~~ Information No. Title AC/Submit A 明明的随机数-set 60/101 B ...
- 大一寒假集训(11)(12)---map,set
大一寒假集训(11)-map 1.查字典 nefu 1678 #include <bits/stdc++.h> using namespace std; map<string,int ...
- 计算机专业、物联网工程大一寒假规划必备篇
物联网工程专业大一寒假规划必备篇 1.我这里主推学<<数据结构>> 2.选择一门编程语言来学习,Python.Java.C++.html+css+js 3.想学机器学习. 4. ...
最新文章
- 单点登陆的技术实现机制
- Gym - 101981I-MagicPotion-最大流
- linux 内存管理优化,Linux性能优化实战 内存篇 阅读笔记
- 途观l怎么使用_官宣!中型SUV质量最新排名出炉:汉兰达失前三,大众途观L上榜!...
- c#怎么设置一个字符串中某个字符的颜色
- hive 操作(五)——常用内置函数
- Exchange2010安装配置篇二 自动安装
- 奇异值分解(SVD) 的 几何意义
- 计算机学院姚茜,武汉理工大学第三届届学位评定委员会
- SpeedFan 控制风扇转速
- 网络神偷 v7.6 免费
- web第三课html课堂笔记
- 【量化课堂】彼得·林奇的成功投资
- 【GD32F310开发板试用】利用I2C接口通过温湿度传感器HDC1080读取当前环境温湿度
- java 跳过法定节假日和双休
- 2022年Java秋招面试必看的 | Linux 面试题
- springboot项目导入idea中环境配置相关问题解决
- UltraISO(软碟通)制作U盘启动安装CentOS 7
- 梯形波的傅里叶级数分解
- 基于VB的COM编程入门教程
热门文章
- 爬虫入门教程⑧— BeautifulSoup解析豆瓣即将上映的电影信息
- Python编程——pickle模块的使用详解(附实例)
- _pickle.UnpicklingError: pickle data was truncated
- Google Voice 保留号码
- 使用keytool生成SSL证书
- Ubuntu中搜狗输入法安装和卸载
- 信息化及计算机相关岗位职责,关于印发《信息化管理工作人员岗位职责》的通知...
- 基于cp-abe算法的访问控制方法在linux下的实现和算法优化,基于CP-ABE的访问控制研究...
- Steam教育在人文研究领域体现的综合素养
- 扔鸡蛋问题 动态规划大法