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。

0 0
原创粉丝点击