来源:互联网 发布:婚礼录像编辑软件 编辑:程序博客网 时间:2024/06/16 10:01

栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
栈是一种LILO(先进后出)数据结构,在很多地方都能用到,编译器,DFS,求表达式的值,进制转换等中都能够用到。
相对于NOIP,它是作为一个很普通的工具,必须掌握的内容,在模拟题中经常能遇到。
不多说,当前也作为复习内容,无BUFF加成,无特效,但RP++

表达式求值

所选练习题目:洛谷P1449 后缀表达式。(纯手工,不使用STL
以下为贴代码过程:

#include<cstdio>#include<cstring>#include<cstdlib>const int MAXN = 1000+10;char s[MAXN];int stack[MAXN],top;inline int pop_t(){     //为了方便,直接把top()与pop()合并    int x = stack[top];    stack[top] = 0;    top--;    return x;} inline void push(int x){  //插入    stack[++top] = x; }int main(){    char c;    int x1 = 0;    while(1){        scanf("%c",&c);        int x,y;        if(c == '@')break;        switch(c){            case '+':x = pop_t();y = pop_t();push(x+y);break;            case '-':x = pop_t();y = pop_t();push(y-x);break;            case '*':x = pop_t();y = pop_t();push(x*y);break;            case '/':x = pop_t();y = pop_t();push(y/x);break;            case '.':push(x1);x1 = 0;break;            default :x1 = x1*10 + c - '0';break;        }    }    printf("%d\n",pop_t());    return 0;}

火车变轨

所选题目:Uva514 铁轨
代码如下:

//栈的使用   火车的模拟 #include<cstdio>#include<iostream>#include<stack>using namespace std;const int MAXN = 1000 + 10;int n,target[MAXN];int main(){    while(scanf("%d", &n)==1){        stack<int> s;    int A = 1 , B = 1;    for(int i = 1; i <= n; i++)       scanf("%d",&target[i]);    int ok = 1;    while(B <= n){        if(A == target[B]){ A++; B++;}        else if(!s.empty() && s.top() == target[B]){ s.pop(); B++;}        else if(A <= n)s.push(A++);        else{ ok = 0; break;}    }    printf("%s\n",ok?"Yes":"No");    }    return 0;}

单调性

栈的单调性在解决一些题目中具有重要作用。
例如:洛谷P1901 发射站

其他的不说,直接说一下思路及贴代码。

思路:第i个发射站发射的能量只能由它两边比它更高的发射站接收,我们可以先只先考虑一边的情况,假设它只向左边发射能量,那么它只能是左边第一个比它高的发射站接收它所发射的能量,假如第i个发射站其左边的发射站高度都比它低那么它所发射的能量将不会被任何一个发射站接收,反之如果其左边的发射站高度都比它高则右边第一个发射站将接受i发射站发射的能量,所以我们可以建造一个高度值栈顶到栈底递增单调栈,维护第i个发射站左边第一个高度大于它的编号。

下面为代码:

#include<cstdio>const int MAXN = 1000000+100;int n,top,h[MAXN],v[MAXN],x[MAXN];int s[MAXN],pos[MAXN];int max(const int &a,const int &b){         //自定义最大值函数     return a > b ? a : b;}int read(){                     //加速输入     int x = 0;    char ch = getchar();    while(ch < '0' || ch > '9')ch = getchar();    while(ch >= '0' && ch <= '9'){        x = x*10 + ch - '0';        ch = getchar();    }    return x;}void add(int p){                        //单调栈维护函数     while(top&&h[p] >= s[top])top--;    //寻找p之前的大于h[p]的第一个数据编号     x[pos[top]] += v[p];                //x代表所接收的能量值     s[++top] = h[p]; pos[top] = p;      //维护栈顶的数据编号 }int main(){    n = read();    for(int i = 1; i <= n; i++)h[i] = read(),v[i] = read();    for(int i = 1; i <= n; i++)add(i);     //左边     top = 0;    for(int i = n; i >= 1; i--)add(i);      //右边     int ans = 0;    for(int i = 1; i <= n; i++)ans = max(ans,x[i]); //更新最大值     printf("%d\n",ans);    return 0;}

RP++

原创粉丝点击