Problem Description: Stack is a commonly used data structure, there are n elements on the top side of the stack to wait for the stack, the top of the stack on the other side is the stack sequence. You already know that there are two kinds of operations on the stack: Push and pop, the former is a stack of elements, and the latter is the top element of the stack pops up. Now, to use these two operations, a sequence of output sequences can be obtained from an action series. You are programmed to calculate and output the total number of output sequences that can be obtained by a series of operations for a given n, computed and 1,2,...,n by the operand sequence.
Analysis: You've seen this before. Is the train pit stop problem, determine whether the sequence is legitimate, was made with the STL stack. This problem only counts the number of times, then, the method is very simple, recursive and dynamic return can be achieved, of course, the stack simulation is certainly OK. It is worth mentioning is an online analysis method (quoted from Shijiazhuang Railway University Liu Li and other papers)
1 Introduction
In the teaching of practical application and data structure course, the stack is very important as a basic structure [1][3][4][6]. Such problems often arise when a given sequence is known, the number of stack sequences is calculated, the sequence of all the stacks is obtained, and the sequence is judged to be a valid stack sequence [5][7]. In [3], the enumeration of the stack sequence is given an introductory description, because the result of the need to use a generating function, [3] but also directly give a conclusion. In this paper, we propose to solve the counting problem of stack sequence by using the "path count between two points", and then we can find out the sequence of all the stacks and determine whether a sequence is a valid one.
2 Problem Analysis
Problem with path count between two points
Problem: Suppose that the square grid lines (5x5) in all road 1 between a and b two point to the right or upward movement from A to B, and there are several paths to point A to point B.
Figure 12 Path graph of the path count problem between points
Analysis: Because the rule can only move right or up from A to B, any point can only be reached from the left or next neighbor of that point, for example, at any point C points can only be reached from D or e points. Therefore, the road from point A to point C can only be composed of these two parts: ① from Point A to point D, then from D to C, ② from point A to point E and from E to C.
Conclusion 1: The number of paths from point A to any point C = number of paths from point A to point D (left neighbor of C) + number of paths from point A to E (lower neighbor of c)
The number of paths from point A to point A is 1 because there is no left neighbor to the point directly above point A, and the problem has been specified to move from A to B only to the right or up. Similarly, the number of paths from point A to the right of point A is 1.
According to conclusion 1, the number of paths from point A to any point is calculated, and the number at the intersection of the grid lines in 1 is shown.
Comparison of operations between stack operations and two-point path count issues
There are two types of stack operations: stack and stack. There are three issues to be aware of: ① all nodes can only be stack after the stack, ② stack when empty, ③ in other cases into the stack, out of the stack arbitrary execution.
There are two actions for the path count problem between two points: move right, move up. There are three issues to be aware of: ① move to the far right and only move upward, ② to the top can only move to the right, ③ in other cases, move up or right to any execution.
From the above analysis, the operation of the stack and the two-point path count problem is very similar to the operation, it may be appropriate to move the stack and the right side, the stack and move up the association. However, after this association, because the two problems are not equivalent (for example, the D point in Figure 1, according to the operation of the stack is not reachable), so we need to analyze all the points in Figure 1.
Analysis of the midpoint of Figure 1 after the operation is associated
First, add the diagonal dashed line from point A to point B in Figure 1. This dashed line divides all points into three categories: the point on the ① dashed line, the point at the top left of the ② dashed line, and the point at the bottom right of the ③ dashed line.
Secondly, according to the operation of the path counting problem between two points, it is easy to obtain: ① from point A to each point on the dotted line, the number of right-shift operations and the number of move-up operations are equal; ② the number of right moves is less than the number of move-up operations when moving from point A to each point on the left ③ moves from point A to each point at the bottom right of the dotted line, the number of right-shift operations performed is greater than the number of move-up operations.
Again, due to any time in the stack operation process must have: the number of times to stack operation ≥ the number of stack operations (equal to the stack empty).
It is obvious that the point in the top left of the dotted line in Figure 1 is not reachable according to the stack, the dotted line is exactly the state of the stack empty, the bottom right of the dotted line can be reached according to the operation of the stack, so consider modifying the path graph in Figure 1.
Improved path map and rules
Remove the point at the top left of the dashed line in Figure 1 as shown in the next 2 (the lower triangle of the 5x5 square grid line).
Figure 2 the reconstructed path map
Provisions: From A to B can only move right or up, right to the stack operation, move up to the stack operation.
According to 2.3 of the analysis can be concluded 2:
① the number of paths from point A to right of a point = 1;
② the number of paths from point A to the leftmost point in each row (considering point B, regardless of point a) = the number of paths from point A to the lower neighbor of the point;
③ number of paths from point A to any other c = number of paths from point A to point D (left neighbor of C) + number of paths from point A to E (lower neighbor of c);
④ according to the operation of the stack from point A to point B, all the points in Figure 2 are reachable;
⑤ 4 nodes in the stack, the stack operation is fully contained in Figure 2;
⑥ expands the ⑤: the stack of N nodes is fully contained in the lower triangle of (n+1) x (n+1) square grid lines.
Here are only a few notes to the conclusion 2 point ⑤: The first point and the other points on the diagonal indicate that the stack is empty, only into the stack (right), and secondly, when moving to the right side of the vertical edge all the elements are already in the stack, only out of the stack (move up); Other points can be arbitrarily stacked (move right) and out of stack (UP). Therefore, the 4 nodes of the stack, the stack operation is fully contained in Figure 2.
From conclusion 2, you can see that the operation of the stack and the path count problem between two points are equivalent in Figure 2. According to conclusion 2, the number of points from point A to any point is calculated, the number at the intersection of the grid line in 2 is shown, the dashed arrow in Figure 2 shows the execution Conclusion 2 ① point, and the solid arrow in Figure 2 indicates the execution Conclusion 2 ③ point.
Conclusion 2 Promotion
Conclusion 2 is extended to the conclusion 3: for the form of 2 ((n+1) x (n+1) square grid line of the lower triangle), the provisions from a to B can only move right or up, right to the stack operation, move up to the stack operation, the number of points from A to B is the number of N nodes out of the stack sequence, And each route from point A to point B represents a sequence of out stacks.
3 Design Implementation
The algorithm for calculating the number of stack sequences of n nodes is implemented by the bottom-up line-by-row, and each row is processed from left to right by point. In addition, when you calculate the value of the current row, you only need to use the value of the previous row; When you calculate each value in each row, the value of the left neighbor is the previous element in the array, the next neighbor is the current element in the array, the previous element of the current element is added to the current element, and the value of the current point is calculated, so in the concrete implementation, Only one array is used to hold the value of the current row. Since the last line has only one number, which is also the first number of the line, according to the ③ point of Conclusion 2, the number is calculated in the penultimate line, so the line does not have to be computed, and the last number in the result of the previous row is taken directly.
4 Conclusion
This method is simple and convenient, does not need to memorize any formula [3], especially for those who do not have a combination of mathematical basis. In addition, according to Figure 2 can also design the algorithm will be in the stack, the operation sequence of the stack out, so that all the stack sequence can be obtained. At the same time, according to Figure 2 can also determine whether a sequence is a valid stack sequence, can solve the [5][7] in the car scheduling problem.
Code: Divided into recursion and the algorithm of this paper to solve
1. Recursive version
#include <iostream>using namespace Std;int Num,n;//sz represents the current stack size, I is a pointer to the wait dispatch sequence void calcunum (int i,int sz) { if (i >n) {//All sequences have been processed num++; return; } Calcunum (i+1,sz+1);//Enter Stack if (sz>0)//Stack { calcunum (i,sz-1); }} int main () { cin>>n; Calcunum (1,0); cout<<num; return 0;}
2, two-point path problem
#include <iostream> #include <stack>using namespace Std;int Num,n;//sz represents the current stack size, I is a pointer to the wait schedule sequence void Calcunum ( int I,int sz) { if (i>n) {//All sequences have been processed num++; return; } Calcunum (i+1,sz+1);//Enter Stack if (sz>0)//Stack { calcunum (i,sz-1); }} void path () { int s[n+1][n+1]; for (int i=0;i<=n;i++) s[0][i]=1; for (int i=1;i<=n;i++) {for (int j=1;j<=n;j++) { if (i < j) S[i][j] = s[i-1][j]+s[i][j-1]; if (i = = j) S[i][j] = S[i-1][j];} } num = S[n][n];} int main () { cin>>n; Path (); cout<<num; return 0;}
The railway connection structure of a train dispatching station is shown in Figure 1.
Where A is the inlet, B is the exit and S is the blind end of the relay. All railways are monorail unidirectional: The train travels only from a to S, then s to B, and no overtaking is allowed . Because carriages can reside in S, the order in which they exit from the B-end may differ from the order in which they are driven from end a. However, the capacity of S is limited, while the carriages in which they reside must not exceed M knots.
A train consisting of n carriages of {1, 2, ..., n} is numbered sequentially. Dispatcher want to know, according to the above traffic rules, these carriages can be {A1, A2, ..., an} order, rearrange and exit from the B end. If so, what should be the order of operation?
input
A total of two lines.
The first behavior is two integers n,m.
The second behavior is a space-delimited n integer that is guaranteed to be an array of {1, 2, ..., n}, indicating the exit sequence {A1,a2,...,an} to be judged feasible.
Output
If the exit sequence is feasible, then the output sequence of operations, where push indicates that the compartment from a into the s,pop means carriages from S into B, each operation occupies a row.
If this is not possible, the output no
The following is the method (imperfect) that I did before on UVA.
#include <iostream> #include <stack>using namespace std;int const MAX = 1000;int Testorder (int n) { stack& Lt;int> train; int Ch[max]; int cura=1,curb=1; for (int i =1; i<=n; i++) { cin>>ch[i]; if (Ch[i] ==0) { return 0; } } while (curb<=n) { if (ch[curb] = = CurA) { curb++; cura++; } else if (!train.empty () && ch[curb] = = Train.top ()) { train.pop (); curb++; } else if (cura<=n) { train.push (cura++); } else{ cout<< "No" <<endl; return 1; } } cout<< "Yes" <<endl; return 1;} int main () { int n; cin>>n; do{ while (Testorder (n) ==1); cin>>n; if (n!=0) cout<<endl; } while (n! = 0); return 0;}
Stack and queue problems in the stack sequence