zoukankan      html  css  js  c++  java
  • 基础数据结构3.1——堆栈

    题目上添加了超链接,大家点一下题目就会自动跳转到Poj原题界面~~              冲鸭冲鸭ヾ(◍°∇°◍)ノ゙。

    前言:

    堆栈相较于其它数据结构的特点是先进后出,常见实现有顺序栈、链栈,做题时顺序栈就足以应对绝大部分题目。常见题型有模拟单调栈(点我一下试试)....总体来说不难。

    3.1.1 Web Navigation (1028)

    题意:使用堆栈模拟Web浏览器的操作,根据不同指令输出对应的结果。

    小笔记:按要求模拟即可,可以通过双栈,也可以自己实现一个可以访问中间变量的栈。

    #include <iostream>
    #include <string>
    #include <stack>
    using namespace std;
    int main()
    {
        stack<string> F, B;
        string URL = "http://www.acm.org/";
        string C;
        do
        {
            cin >> C;
            switch (C[0])
            {
            case 'V':
                B.push(URL);
                while (!F.empty())
                    F.pop();
                cin >> URL;
                cout << URL << endl;
                break;
            case 'B':
                if (B.empty())
                    cout << "Ignored" << endl;
                else
                {
                    F.push(URL);
                    URL = B.top();
                    B.pop();
                    cout << URL << endl;
                }
                break;
            case 'F':
                if (F.empty())
                    cout << "Ignored" << endl;
                else
                {
                    B.push(URL);
                    URL = F.top();
                    F.pop();
                    cout << URL << endl;
                }
                break;
            }
        } while (C[0] != 'Q');
        return 0;
    }
    

      或者手动实现栈

    #include <iostream>
    #include <string>
    using namespace std;
    string web[105]; //自己动手,实现可以访问栈中位置元素的栈,从而避免双栈
    int main()
    {
        web[0] = "http://www.acm.org/";
        string s, tmp;
        int i = 0; //记录指针
        while (cin >> s)
        {
            if (s == "QUIT")
                break;
            if (s == "VISIT")
            {
                string ch;
                cin >> ch;
                web[++i] = ch;
                tmp = ch; //记录最新入栈web
                cout << ch << endl;
            }
            if (s == "BACK")
            {
                i--;
                if (i <= -1) //注意下标越界问题
                    i = -1, cout << "Ignored" << endl;
                else
                    cout << web[i] << endl;
            }
            if (s == "FORWARD")
            {
                if (tmp == web[i])
                    cout << "Ignored" << endl;
                else
                {
                    if (i < 0)
                        i = 0;
                    cout << web[++i] << endl; //第一个页面不可能是前进得来,所以此处为++i
                }
            }
        }
        return 0;
    }
    

      

    3.1.2 Bad Hair Day (3250)

    题意:n头牛站成一排,每头牛高度分别为h,从左边第1头牛向右看,到下一个比它高的牛之前,之间比它低的牛的数目计为c,计算这n头牛的c值的和。

    小笔记:经典单调栈问题,简单题

    #include <cstdio>
    #include <stack>
    using namespace std;
    int main()
    {
        int n;
        long long ans = 0;
        stack<long long> c;
        scanf("%d", &n);
        while (n--)
        {
            int h;
            scanf("%d", &h);
            while (!c.empty() && h >= c.top())
                c.pop();
            ans += c.size();
            c.push(h);
        }
        printf("%lld
    ", ans);
        return 0;
    }
    

      

    3.1.3 Rails (1363)

    题意:判断一个队列是否能用另一个队列通过入栈出栈操作形成。

    小笔记:依次入栈比对即可。简单题

    #include <cstdio>
    #include <stack>
    using namespace std;
    bool solve(int n)
    {
        int a = 1;
        bool p = true; //判断是否能够成功输出B
        stack<int> S;
        while (n--)
        {
            int b; //B序列中的数字
            scanf("%d", &b);
            if (!b)
                return false;
            while (a <= b)
                S.push(a++);
            if (!S.empty() && S.top() == b)
                S.pop();
            else
                p = false;
        }
        printf(p ? "Yes
    " : "No
    ");
        return true;
    }
    int main()
    {
        int n;
        while (scanf("%d", &n) && n)
        {
            while (solve(n))
                ;
            printf("
    ");
        }
        return 0;
    }
    

      

    3.1.4 Terrible Sets (2082)

    题意:依次给出n个矩形的长和高,这些矩形分布在第一象限,底边在x轴并列排放,求由这些矩形覆盖的区域所组成的最大矩形的面积。

    小笔记:单调栈例题,题解链接给大家了,非常建议去听一下。

    #include <cstdio>
    #include <stack>
    using namespace std;
    struct Rectangle
    {
        int w;
        int h;
    };
    int W;   //记录扫描到的宽度w的和
    int ans; //最大面积
    stack<Rectangle> s;
    //用新加入的矩形的高h对栈中元素进行扫描
    void scan(int h)
    {
        W = 0;
        while (!s.empty() && s.top().h > h)
        {
            W += s.top().w;
            ans = max(ans, W * s.top().h);
            s.pop();
        }
    }
    int main()
    {
        int n;
        while (scanf("%d", &n) && ~n)
        {
            ans = 0;
            int H = 0; //记录最后入栈的矩形的高度h
            while (n--)
            {
                Rectangle r;
                scanf("%d%d", &r.w, &r.h);
                if (r.h < H)
                {
                    scan(r.h);
                    W += r.w;
                    r.w = W;
                }
                s.push(r);
                H = r.h;
            }
            scan(0); //所有矩阵处理完之后还需要再扫描一遍
            printf("%d
    ", ans);
        }
        return 0;
    }
    

      

    3.1.5 Code (1780)

    题意:设计软件来破译n位的数字密码,生成一个长度为10n+n-1的数字序列,只要序列中出现正确密码,即可破译,数字序列应该包含所有组合,输出这个序列(字典序最小)。

    小笔记:啊,这道题看起来太痛苦了...十分劝退,是个欧拉回路(一笔画)问题。挺难的,应该可以算省赛金牌题了。

    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N = 1000010;
    const int P[] = {1, 10, 100, 1000, 10000, 100000, 1000000};
    int S[N];  //自定义堆栈
    int p[N];  //记录序列下一位的值
    bool v[N]; //记录该点是否被访问
    int main()
    {
        int n;
        while (scanf("%d", &n) && n)
        {
            int m = P[n];
            fill(v, v + m, false);
            fill(p, p + m, 0);
            int top = 0;
            S[top] = 0;
            v[0] = true;
            while (top < m - 1)
            {
                int i = S[top];
                if (p[i] == 10)
                {
                    top--;
                    v[i] = false;
                    p[i] = 0;
                    continue;
                }
                p[i]++;
                int j = (i * 10 + p[i] - 1) % m;
                if (!v[j])
                {
                    S[++top] = j;
                    v[j] = true;
                }
            }
            for (int i = 1; i < n; i++)
                putchar('0');
            for (int i = 0; i < m; i++)
                putchar(S[i] % 10 + '0');
            printf("
    ");
        }
    }
    

      

  • 相关阅读:
    表格标签
    常用标签
    标签笔记
    基础标签与格式
    态度!
    如何修改数据 练习
    增删查练习
    登陆注册练习
    PHP 数据访问
    PHP 基础知识测试题 答案分析
  • 原文地址:https://www.cnblogs.com/thx2199/p/15116521.html
Copyright © 2011-2022 走看看