How to cross the river
1. Question proposal
Each of the three merchants took one entourage to cross the river by boat. A boat could only accommodate two people, and they planned for themselves. On any bank of the river, when the number of followers is more than the number of businessmen, the merchant may be in danger. But how can the power of boat crossing be put in the hands of businessmen, and how can the businessmen safely cross the river?
This is the famous commercial servant crossing the river. After some logic thinking, this kind of intellectual games can find a solution. In this case, it is required to promote the problem to any commercial servant or vessel capacity. In general, we should establish a mathematical model and program the solution.
2. Model Establishment and symbol description
The Log Service Log is m, and the ship capacity is c.
Note that xk is the number of merchants on the shore before the k crossing the river, and the number of followers is yk, k = 1, 2 ,..., Xk, yk = 0, 1, 2 ,..., M,
The two-dimensional vector sk = (xk, yk) is defined as the State, and the State set under the security crossing conditions is defined as the allowed state space, recorded as S
For details, see:
Here we useBFS algorithm (breadth-first search algorithm)Programming to solve the problem of crossing the river. The BFS algorithm is one of the most typical graph search algorithms. In this question, we can find the shortest path, that is, the minimum number of steps to cross the river. The algorithm is described as follows:
Create a status queue q, which is a first-in-first-out queue.
(1) Add the starting point (n, n) to the queue q and mark (n, n) as accessed.
(2) Leave the first node of q to the queue, and then add all inaccessible permitted States of the node to q
(3) mark all new states as accessed. If there is a termination state (), the problem is resolved and the algorithm ends.
(4) If the queue q is empty, the problem is not resolved and the algorithm ends.
(5) Go to (2) Execute
Analysis:
Observe the execution process of the BFS algorithm. The algorithm first adds all the statuses that are transferred from the initial status to the queue. If the status is not terminated, then, we will continue to add all the statuses that are transferred two times from the starting status to the queue ......
Because the queue is FIFO, you can always ensure that the status with the minimum number of status transfer steps is at the forefront of the queue, and first they need to expand the next layer of status.
Therefore, each status that is added to the queue is in the shortest path (minimum number of state transfer steps), because if a shorter path exists, the status on this path will be extended earlier, join the status queue earlier (the status with fewer steps is placed at the front of the Status Queue ).
When the terminated state is added to the queue, the path to the terminated state is also the shortest path, that is, a solution with the minimum number of status transfer steps is obtained.
If the status queue is empty at a certain time and never reaches the end state, it means that all nodes in the starting state can be accessed and there is no end state, that is, the end state cannot be reached, no solution.
Analysis of the Relationship between the commercial servant logarithm and the ship capacity and the problem:
Servant logarithm |
Boat capacity |
1, 2, 3 |
≥2 |
4, 5 |
≥3 |
≥6 |
≥4 |
Code:
# Include <bits/stdc ++. h> # include "windows. h "# define MAX_SIZE 1010 using namespace std; struct CNode {int x; // x coordinate int y; // y coordinate int flag; // whether the vertex int dir can be walked; // mark the CNode * p in the sailing direction; // parent node pointer}; CNode G [MAX_SIZE] [MAX_SIZE] [2]; // state space coordinate, access int V [MAX_SIZE] [MAX_SIZE] [2]; // access tag deque <CNode> q; // search queue int num; // the logarithm of the Business servant int cap; // ship capacity bool solve; // unmark int steps; // The number of steps void Init (); // initialize void BFS (); // BFS search void Output (CNode * p); // Output int Main () {Init (); // initialize while (! Q. empty ()&&! Solve) {// BFS search BFS ();} if (! Solve) cout <"\ n problem unsolved \ n"; else {cout <"\ n cross-river solution: \ n "; output (& G [0] [0] [1]); // return cout Output <"minimum required" <steps <"step \ n ";} return 0;} void Init () {cout <"total commercial servant logarithm:"; cin> num; cout <"ship capacity:"; cin> cap; int I, j; for (int I = 0; I <= num; I ++) {for (int j = 0; j <= num; j ++) {// initialize the status space G [I] [j] [0]. x = G [I] [j] [1]. x = I; // coordinate x G [I] [j] [0]. y = G [I] [j] [1]. y = j; // y G [I] [j] [0]. flag = G [I] [j] [1]. flag = 0; // both initialize to 0G [I] [j] [0]. p = G [I] [j] [1]. p = NULL; // node G [I] [j] [0]. dir =-1; // The left or lower G [I] [j] [1]. dir = 1; // The right or top V [I] [j] [0] = V [I] [j] [1] = 0; // unaccessed }}for (I = 0; I <= num; I ++) {// mark a feasible point as 1G [0] [I] [0]. flag = G [num] [I] [0]. flag = G [I] [I] [0]. flag = 1; G [0] [I] [1]. flag = G [num] [I] [1]. flag = G [I] [I] [1]. flag = 1;} G [num] [num] [0]. flag = G [num] [num] [1]. flag = 0; // set the initial state to 0 solve = false in the upper right corner; // mark whether the problem is resolved or not. push_back (G [num] [num] [0]); // The initial entry queue steps = 0; // the minimum number of river crossings} void BFS () {int x, y; // The int dx, dy coordinates of the first line; // The int nx, ny coordinates of the changed line. // The int dir coordinate after the trip; // if (q. empty () | solve) // if the search queue is empty or has a solution, exit the search return; x = q. front (). x; // retrieve the first coordinate of the team y = q. front (). y; dir = q. front (). dir; q. pop_front (); // for (dx = 0; dx <= cap; dx ++) {for (dy = 0; dy <= cap-dx; dy ++) {// enumerate all possible states nx = x + dx * dir; ny = y + dy * dir; if (nx <0 | nx> num | ny <0 | ny> num) // coordinates cross-border continue; if (G [nx] [ny] [0]. flag = 0) // reach the non-feasible point continue; if (dx = 0 & dy = 0) // The coordinate does not change continue; if (dir> 0 & V [nx] [ny] [1] = 1) // This point has been accessed to continue; if (dir <0 & V [nx] [ny] [0] = 1) // This point has been accessed to continue; if (dir> 0) {// put into the queue G [nx] [ny] [0]. p = & G [x] [y] [1]; q. push_back (G [nx] [ny] [0]);} else {// put into the queue G [nx] [ny] [1]. p = & G [x] [y] [0]; q. push_back (G [nx] [ny] [1]);} if (dir> 0) // mark accessed V [nx] [ny] [1] = 1; else V [nx] [ny] [0] = 1; if (nx = 0 & ny = 0) {// reach the end point solve = true; return ;}}} void Output (CNode * p) {// return the traversal result if (p-> p = NULL) {cout <"(" <p-> x <"," <p-> y <") \ n"; return ;} output (p-> p); cout <"(" <p-> x <"," <p-> y <") \ n "; steps ++ ;} /*---3: * 4 ********* * 5 */
Run: