某城市有一个火车站,铁轨铺设如下图所示。有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\n", 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\n", ok ? "Yes" : "No");
24     }
25     return 0;
26 }
View Code
 posted on 2016-04-04 20:22  tostring_char  阅读(686)  评论(0编辑  收藏  举报