C++栈和队列
来源:互联网 发布:侠盗飞车3罪恶都市mac 编辑:程序博客网 时间:2024/05/01 00:56
使用标准库的栈和队列时,先包含相关的头文件
#include<stack>
#include<queue>
定义栈如下:
stack<int> s;
定义队列如下:
queue<int> q;
栈提供了如下的操作
//s.empty() 如果栈为空返回true,否则返回false //s.size() 返回栈中元素的个数 //s.pop() 删除栈顶元素但不返回其值 //s.top() 返回栈顶的元素,但不删除该元素 //s.push() 在栈顶压入新元素
队列提供了下面的操作
q.empty() 如果队列为空返回true,否则返回false q.size() 返回队列中元素的个数 q.pop() 删除队列首元素但不返回其值 q.front() 返回队首元素的值,但不删除该元素 q.push() 在队尾压入新元素 q.back() 返回队列尾元素的值,但不删除该元素
栈: 例题 poj 2082 Terrible Sets
题意:
紧贴x轴有一些互相挨着的矩形,给定每个矩形的长宽,问它们可以形成的最大矩形是多少。
思路:
用栈来做,将矩形入栈,保持栈中的元素高度递增,如果即将入栈的高度data.h比栈顶元素的高度lasth小,则退栈。一直退到可以保持栈顶元素高度递增的那个元素x,在退栈过程中统计由lasth至x之间可以形成的最大矩形面积s,记录由lasth至x之间矩形总宽度totalw,在弹出这些元素之后再向栈中压入一个高度为data.h, 宽度为totalw + data.w的矩形,然后继续读入下一个矩形。最后再扫描一遍就好了。
代码:
#include <iostream>#include <stack>#include <cstdio>using namespace std;struct rec {//矩形 int w, h;//宽和高}data;int main() { int n, ans, i, lasth, totalw, curarea; while(scanf("%d", &n) && n != -1) { ans = 0; stack<rec>s; lasth = 0;//上次进栈的矩形的高度 for(i = 0; i < n; i++) { scanf("%d%d", &data.w, &data.h); if (data.h >= lasth) { s.push(data);//进栈 }else { totalw = 0;//总宽 curarea = 0;//当前面积 while(!s.empty() && s.top().h > data.h) { totalw += s.top().w; curarea = totalw*s.top().h; if (curarea > ans) ans = curarea; s.pop(); } totalw += data.w; data.w = totalw; s.push(data);//新矩形压栈 } lasth = data.h; } totalw = 0; curarea = 0; while(!s.empty()) {//最后再扫描一遍 totalw += s.top().w; curarea = totalw*s.top().h; if (curarea > ans) ans = curarea; s.pop(); } printf("%d\n", ans); } return 0;}
直接用数组来做;
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <stack>using namespace std;const int maxn = 50008;long long h[maxn], len[maxn];int main() { long long res; int n, wi, hi, i; while(scanf("%d", &n) && (n+1)) { i = 0; res = 0; while(n--) { scanf("%d%d", &wi, &hi); if (i == 0) { h[i] = hi; len[i++] = wi; continue; } int tmp = 0; if (h[i-1] > hi) tmp = 1; while(h[i-1] > hi && i > 0) { i--; res = max(res, h[i]*len[i]); } for(int j = 0; j < i; j++) len[j] += wi; if (tmp) len[i] += wi;//如果进了while循环就跟for循环做的处理一样 else len[i] = wi;//如果没进循环,就直接就是自己的长度 h[i++] = hi; } while(i > 0) { i--; res = max(res, h[i]*len[i]); } printf("%I64d\n", res); }return 0;}
总结:用数组可以对所有元素都进行处理,而栈只可以对栈顶元素处理,不知道用栈干什么0.0!
例题 :队列 poj 2259 Team Queue
题意:就像要排一只很长的队伍,但是不想从最后面排起,于是就会从头到尾看看队伍中有没有熟人在,如果有,就插队到熟人后面;如果没有,就只能从队尾慢慢排了。输入一开始是说明哪些人是一组的,后面才是入队与出队的操作;(一开始没看懂题目,没搞懂输入,一下顿悟了);
发两个:
1用库函数做的:
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <map>using namespace std;int nCaseNum, nNum;queue<long> nQue[1001]; //储存每个队列queue<int> nS; //储存队列号int nM[1000000]; //元素与队列号的映射表bool nFlag[1001]; //标识有无同组元素void solve() { string nCommand; long nElem; cout<<"Scenario #"<<++nCaseNum<<endl; while(cin>>nCommand, nCommand != "STOP") { if (nCommand == "ENQUEUE") { cin>>nElem; if(!nFlag[nM[nElem]]) { //若还没有同组元素 nFlag[nM[nElem]] = true; nS.push(nM[nElem]); //将组号进队列 } nQue[nM[nElem]].push(nElem); }else if (nCommand == "DEQUEUE") { int nId = nS.front(); //首先处理最先进队列的那组元素 cout<<nQue[nId].front()<<endl; nQue[nId].pop(); if (nQue[nId].empty()) { nS.pop(); nFlag[nId] = false; } } } cout<<endl;}void init() {//初始化很重要 for(int i = 0; i != nNum; ++i) { nFlag[i] = false; while(!nQue[i].empty()) nQue[i].pop(); } while(!nS.empty()) nS.pop();}void input() { int nElem, elemNum; for(int i = 0; i != nNum; ++i) { cin>>elemNum; for(int j = 0; j != elemNum; ++j) { cin>>nElem; nM[nElem] = i; } }}int main() { nCaseNum = 0; while(cin>>nNum, nNum) { init(); input(); solve(); }return 0;}内存 1600k 时间 900ms
2 用结构体:
代码:
#include <iostream>#include <cstring>#include <cstdio>using namespace std;const int maxn = 1000000;const int ele = 1008;char c[16];struct que { //队列的结构体 int l, r; int st[ele];}que1, queplus[ele];int a[maxn];//元素与队列号的映射表int main() { int n, t, x, i, j, k = 1; while(scanf("%d", &n) && n) { que1.l = que1.r = 0; //初始化很重要 for(i = 0; i < ele; i++) queplus[i].l = queplus[i].r = 0; printf("Scenario #%d\n", k++); //忘记++; i = 0; while(n--) { scanf("%d", &t); while(t--) { scanf("%d", &x); a[x] = i; } i++; } while(scanf("%s", c) && strcmp(c, "STOP")) { if (!strcmp(c, "ENQUEUE")) { scanf("%d", &x); j = a[x]; if (queplus[j].l == queplus[j].r) //队列为空就说明x是第一个 que1.st[que1.r++] = j; queplus[j].st[queplus[j].r++] = x; } else{ j = que1.st[que1.l]; printf("%d\n", queplus[j].st[queplus[j].l++]); if (queplus[j].l == queplus[j].r) //这组出所有元素出完后,大队列首元素出队列 que1.l++; } } printf("\n"); } return 0;}
wa了很多次,总结不要小看输入的这些操作,主要细心;
内存4800k 时间 270ms
比较:用数组的节构体时间快很多,还有很多操作是库函数没有的;但用库函数写起来比较简洁0.0。
- C++:栈和队列
- 数据结构-------C栈和队列
- C实现栈和队列
- 【C语言/C++】 栈和队列
- C语言实现,顺序队列,循环队列,和栈!
- C/C++中的堆、栈和队列
- 栈和队列 C语言实现
- 数据结构与算法(C#)--栈和队列
- 数据结构伪C代码:栈和队列
- 【C++】STL队列和栈的使用
- 栈和队列的操作(c)
- 栈和队列(C语言版)
- 括号分配(栈和队列)C
- c/c++数据结构 栈和队列
- 【数据结构】【C++STL】栈和FIFO队列
- (C++)栈和队列的模拟实现
- 栈和队列--队列
- 【栈和队列】队列
- 竖式问题--c
- LeetCode -- Divide Two Integers
- javaScript创建对象
- matlab PCA-SVD简单地实现特征脸方法(Eigenface)
- java.lang.UnsupportedClassVersionError的产生原因和解决办法深度剖析
- C++栈和队列
- 使用Octave音频处理(三):数学技术处理音频文件
- android用JSONObject和JSONArray解析json格式数据
- 转
- 最短路径四大算法核心Code
- 第五届蓝桥杯软件类省赛真题-JAVA-A-2_李白打酒
- gstreamer常用的指令汇总
- hdu 1698 Just a Hook
- 宏函数与自定义函数的区别与优缺点