zoukankan      html  css  js  c++  java
  • 《算法竞赛入门经典》6.1.2栈和队列-铁轨

      某城市有一个火车站,铁轨铺设如下图所示。有n节车厢从A方向驶入车站,按进站顺序编号为1~n。你的任务是让它们按照某种特定的顺序进入B方向的铁轨并使出车站。为了重组车厢,你可以借助中转站C;这是一个可以停放任意多节车厢的车站,但由于末端封顶,驶入C的车厢必须按照相反的顺序驶出C。对于每个车厢,一旦从A进入C,就不能再回到A了;一旦从C进入B,就不能回到C了。换言之,在任意时刻,只有两种选择:A->C和C->B。
    样例输入:
    5
    1 2 3 4 5
    5
    5 4 1 2 3
    6
    6 5 4 3 2 1
    样例输出:
    Yes
    No
    Yes

     1 #include <stdio.h>
     2 #define MAXN 1000 + 10
     3 int n, target[MAXN];
     4 
     5 int main(void)
     6 {
     7     while(scanf("%d", &n) == 1)
     8     {
     9         int stack[MAXN], top = 0;
    10         int A = 1, B = 1;
    11         for(int i = 1; i <= n; i++)
    12             scanf("%d", &target[i]);
    13         int ok = 1;
    14         while(B <= n)
    15         {
    16             if(A == target[B]) { A++; B++; }    //车厢按顺序进出中转站C,则跳出循环
    17             else if(top && stack[top] == target[B]) { top--; B++; }//若车厢按逆序进中转站C,则跳出循环
    18             else if(A <= n) stack[++top] = A++;    //调整车厢为逆序出中转站C
    19             else { ok = 0; break; }                //车厢既不是按顺序,也不是按逆序进出中转站C
    20         }
    21         printf("%s
    ", ok ? "Yes" : "No");
    22     }
    23     return 0;
    24 }
    View Code

    分析:
      1.栈:在中转站C中,车厢符合后进先出的原则,称为栈,即LIFO表;其中LIFO代表Last In First Out。由于栈只有一端生长,实现时只需要一个数组stack和栈顶指针(始终指向栈顶元素)。
      2.对于第二种输入情况:
        B <= n        A <= n       stack[++top] = A++;
        1 <= 5        1 <= 5        stack[1] = 1; top = 1; A = 2;
                      2 <= 5        stack[2] = 2; top = 2; A = 3;
                      3 <= 5        stack[3] = 3; top = 3; A = 4;
                      4 <= 5        stack[4] = 4; top = 4; A = 5;
                      5 <= 5        stack[5] = 5; top = 5; A = 6;
        top&&stack[top]==target[B]               top--; B++;
        5 && 5==5                                  top = 4 ; B = 2;
        4 && 4==4                                  top = 3 ; B = 3;
        3 && 3==1                                  跳出while循环
      3.为了方便,数组下标均从1开始。例如:target[1]是指目标序列中第一个车厢的编号,stack[1]是指栈底元素(栈空当且仅当top=0)。

    C++提供了一种更加简单的处理方式—STL队列:

     1 #include <cstdio>
     2 #include <stack>
     3 using namespace std;
     4 #define MAXN 1000 + 10
     5 int n, target[MAXN];
     6 
     7 int main(void)
     8 {
     9     while(scanf("%d", &n) == 1)
    10     {
    11         stack<int> s;
    12         int A = 1, B = 1;
    13         for(int i = 1; i <= n; i++)
    14             scanf("%d", &target[i]);
    15         int ok = 1;
    16         while(B <= n)
    17         {
    18             if(A == target[B]) { A++; B++; }    //车厢按顺序进出中转站C,则跳出循环
    19             else if(!s.empty() && s.top() == target[B]) { s.pop(); B++; }//若车厢按逆序进中转站C,则跳出循环
    20             else if(A <= n) s.push(A++);        //调整车厢为逆序出中转站C
    21             else { ok = 0; break; }                //车厢既不是按顺序,也不是按逆序进出中转站C
    22         }
    23         printf("%s
    ", ok ? "Yes" : "No");
    24     }
    25     return 0;
    26 }
    View Code
    亲爱的读者:如果觉得本文对你有所帮助,请点击推荐,分享给其他人!
  • 相关阅读:
    java 二维码图片生成工具类
    我的PHP学习过程
    js简单表格操作
    在同一个textarea文本框中设置不同的字体
    基础入门--创建项目
    异常处理方式
    2019年度的瞎几把总结
    WebAPI 返回值
    关于背景色
    使用echarts进行画图
  • 原文地址:https://www.cnblogs.com/zhuangwei/p/5352781.html
Copyright © 2011-2022 走看看