C++栈和队列

使用标准库的栈和队列时,先包含相关的头文件

#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值