Main Topic
Push box game basic gameplay, to push the box to the destination of the minimum number of push (not the total number of people moving) move the path.
Problem Analysis
to find the shortest path search problem, using BFS. Note that the problem is driven by the least number of times, so the box movement as a state, the box to move the minimum number of times to reach the destination path, and then on the path of the inflection point on the basis of the search for people to move the BFS again.  
BFS set BFS.  
All search problems, dynamic planning problems, each step of the program should be clear, Detailed (primarily, it is possible to completely save the required information, rather than a large amount of data) record status. Each cell in this topic can be entered in four different directions, so when recording a state, each point needs to be recorded and in which direction it is entered.  
when I realized it, I first searched the first layer of BFS to find the shortest moving path of the box. The center records the previous point of each point, and finally the forward moving path of the box, and then find out the inflection point where the person should move, the BFS again, the middle is also saved each point of the previous points, and finally rolled forward path. This leads to a long code length →_→!!!  
doing so is a good deal when the amount of data that each node needs to save is relatively large. But each node needs to save just one character, and a total of no more than 400 points, even if all are saved with a string, memory can be dealt with. It's really ingenious to look at people on the Internet that are implemented in this way! See poj_1475
#define _crt_secure_no_warnings#include<stdio.h> #include <queue> #include <string.h> #include < stack>using namespace std; #define Max_castle_size 24#define INFINITE 1 << 30char gcastle[max_castle_size][max_ Castle_size];bool gwalkvisited[max_castle_size][max_castle_size];int GRow, Gcol;int gBoxPos[2];int gPeoplePos[2]; int Gtargetpos[2];int Gmoveinc[5][2] = {{1, 1}, {0,-1}, {1, 0}, {-1, 0}, {0, 1}};char gwalkdirchar[5] = {' t ' , ' W ', ' s ', ' n ', ' E '};char gpushdirchar[5] = {' T ', ' W ', ' s ', ' n ', ' e '};struct pushnode{int pre_row;int pre_col;int pre_ Dir Pushnode (int p_r = 0, int p_c = 0, int p_d = 0):p re_row (P_r), Pre_col (P_c), Pre_dir (p_d) {};}; Pushnode gpushnodes[max_castle_size][max_castle_size][4];struct walknode{int pre_row;int pre_col;int dir_from_pre; Walknode (int p_r = 0, int p_c = 0, int d = 0):p re_row (P_r), Pre_col (P_c), Dir_from_pre (d) {};}; Walknode gwalknodes[max_castle_size][max_castle_size];struct Peoplemovenode{bool arrive_by_walk;int row;inT col;int dir_to_next;int Box_x;int box_y; Peoplemovenode (bool W = true, int r = 0, int c = 0, int d = 0, int bx = 0, int by = 0): Arrive_by_walk (W), Row (R), col (c), Dir_to_next (d), box_x (BX), box_y (by) {};void SetInfo (bool W, int r, int c, int. D, int bx, int by) {Arrive_by_walk = W;row = R;col = C;dir_to_next = d;box_x = Bx;box_y = by;}}; Stack<peoplemovenode> gpushnodestack;void Input () {memset (Gcastle, ' # ', sizeof (Gcastle)); for (int row = 1; row < = GRow; row++) {GetChar (); for (int col = 1; Col <= Gcol; col++) {scanf ("%c", &gcastle[row][col]); if (gcastle[row][col] = = ' B ' {Gboxpos[0] = row;gboxpos[1] = col;} if (gcastle[row][col] = = ' S ') {gpeoplepos[0] = row;gpeoplepos[1] = col;} if (gcastle[row][col] = = ' T ') {gtargetpos[0] = row;gtargetpos[1] = col;}}} void Traceway (int start_x, int start_y, int cur_x, int cur_y, bool walk) {int pre_x = Gwalknodes[cur_x][cur_y].pre_row;int pre_y = gwalknodes[cur_x][cur_y].pre_col;if (start_x = = cur_x && start_y = cur_y) {//char dir = walk ? Gwalkdirchar[gwalknodes[cur_x][cur_y].dir_from_pre]: gpushdirchar[gwalknodes[cur_x][cur_y].dir_from_pre];// printf ("%c", dir); return;} Traceway (start_x, start_y, pre_x, pre_y, walk); char dir = walk? Gwalkdirchar[gwalknodes[cur_x][cur_y].dir_from_pre]: Gpushdirchar[gwalknodes[cur_x][cur_y].dir_from_pre];p rintf ("%c", dir);} void Findminstepway (int start_x,int start_y, int end_x, int end_y, int box_x, int box_y) {memset (gwalknodes, 0, sizeof (Gwal Knodes) Queue<pair<int, int> > Q;pair<int, int> pos_pair (start_x, start_y); gWalkNodes[start_x][ Start_y].pre_row = -1;gwalknodes[start_x][start_y].pre_col =-1; Q.push (Pos_pair); while (! Q.empty ()) {Pos_pair = Q.front (); Q.pop (); if (Pos_pair.first = = end_x && Pos_pair.second = = end_y) {traceway (start_x, start_y, end_x, end_y, true); r Eturn;} for (int i = 1; I <= 4; i++) {int next_x = Pos_pair.first + gmoveinc[i][0];int next_y = Pos_pair.second + gmoveinc[i][1] ; if (gcastle[next_x][next_y]! = ' # ' &&!gwalknodes[next_x][Next_y].pre_row && (next_x! = box_x | | next_y! = box_y)) {gwalknodes[next_x][next_y].pre_row = Pos_pair.first; Gwalknodes[next_x][next_y].pre_col = Pos_pair.second;gwalknodes[next_x][next_y].dir_from_pre = i; Q.push (Pair<int, int> (next_x, next_y));}}}} People from People_x, people_y departure, can walk to (can not push the box) pos_x, pos_y, box located in Box_x, Box_ybool canpushfrompos (int pos_x, int pos_y, int pe ople_x, int people_y, int box_x, int box_y) {if (gcastle[pos_x][pos_y] = = ' # ') {return false;} if (pos_x = = people_x && pos_y = = people_y) {return true;} Memset (gwalkvisited, False, sizeof (gwalkvisited)); gwalkvisited[people_x][people_y] = True;gwalkvisited[box_x][box_ Y] = true;queue<pair<int, int> >q;pair<int, int> pos_pair (people_x, people_y); Q.push (Pos_pair); while (! Q.empty ()) {Pos_pair = Q.front (); Q.pop (); if (Pos_pair.first = = Pos_x && Pos_pair.second = = pos_y) {return true;} for (int i = 1; I <= 4; i++) {int next_x = Pos_pair.first + gmoveinc[i][0];int next_y = Pos_pair.seconD + gmoveinc[i][1];if (Gwalkvisited[next_x][next_y] | | gcastle[next_x][next_y] = = ' # ') {continue;} Gwalkvisited[next_x][next_y] = true; Q.push (Pair<int, int> (next_x, next_y));}} return false;} void Setnodestack () {while (!gpushnodestack.empty ()) {Gpushnodestack.pop ();} int cur_x = Gtargetpos[0], cur_y = Gtargetpos[1];int Last_dir = -1;for (int i = 1; I <= 4; i++) {if (gpushnodes[cur_x][c Ur_y][i].pre_row) {last_dir = I;break;}} int pre_x = Gpushnodes[cur_x][cur_y][last_dir].pre_row;int pre_y = Gpushnodes[cur_x][cur_y][last_dir].pre_col; Peoplemovenode Move_node (False, pre_x, Pre_y, last_dir,cur_x, cur_y); Gpushnodestack.push (move_node); cur_x = Pre_x;cur _y = Pre_y;while (True) {///printf ("cur x =%d, cur y =%d\n", cur_x, cur_y); if (cur_x = = Gboxpos[0] && cur_y = = GB Oxpos[1]) {pre_x = cur_x-gmoveinc[last_dir][0];p re_y = cur_y-gmoveinc[last_dir][1];if (pre_x = = GPeoplePos[0] && ; Pre_y = = Gpeoplepos[1]) {Move_node. SetInfo (False, pre_x, Pre_y, Last_dir, cur_x, cur_y); gpushnodestAck.push (Move_node);} Else{move_node. SetInfo (True, pre_x, Pre_y, Last_dir, cur_x, cur_y); Gpushnodestack.push (Move_node); Move_node. SetInfo (False, Gpeoplepos[0], gpeoplepos[1], Last_dir, cur_x, cur_y);//people starting from, Arrive_by_walk and Last_dir are not used, Set Gpushnodestack.push (Move_node);} break;} Description of the change to if (Gpushnodes[cur_x][cur_y][last_dir].pre_dir) {//turn occurred, record the position of the person after the turn pre_x = cur_x-gmoveinc[last_dir][0] ;p re_y = Cur_y-gmoveinc[last_dir][1];move_node. SetInfo (True, pre_x, Pre_y, Last_dir, cur_x, cur_y); Gpushnodestack.push (move_node); last_dir = Gpushnodes[cur_x][cur_y ][last_dir].pre_dir;pre_x = Gpushnodes[cur_x][cur_y][last_dir].pre_row;pre_y = Gpushnodes[cur_x][cur_y][last_dir]. Pre_col;move_node. SetInfo (False, pre_x, Pre_y, Last_dir, cur_x, cur_y); Gpushnodestack.push (Move_node);} int tmp = cur_x;cur_x = Gpushnodes[cur_x][cur_y][last_dir].pre_row;cur_y = Gpushnodes[tmp][cur_y][last_dir].pre_col;}} void Movebox () {Peoplemovenode move_node_from = Gpushnodestack.top (); Gpushnodestack.pop (); Peoplemovenode moVe_node_to;while (!gpushnodestack.empty ()) {move_node_to = Gpushnodestack.top (); Gpushnodestack.pop (); if (Move_node_ To.arrive_by_walk) {Findminstepway (Move_node_from.row, Move_node_from.col, Move_node_to.row,move_node_to.col, move _node_to.box_x, move_node_to.box_y);} Else{int cur_x = move_node_from.row, cur_y = Move_node_from.col;while (cur_x! = Move_node_to.row | | cur_y! = move_node_to. COL) {cur_x = cur_x + gmoveinc[move_node_from.dir_to_next][0];cur_y = cur_y + gmoveinc[move_node_from.dir_to_next][1]; printf ("%c", Gpushdirchar[move_node_from.dir_to_next]);}} Move_node_from = move_node_to;}} struct posdirpair{unsigned char row;unsigned char col;unsigned char dir_from_pre;void SetInfo (unsigned char r, unsigned ch Ar c, unsigned char dir) {row = R;col = C;dir_from_pre = dir;}}; void Solve (int cases) {printf ("Maze #%d\n", cases), memset (gpushnodes, 0, sizeof (gpushnodes)); queue<posdirpair>q ; Posdirpair Pos_dir_pair;pos_dir_pair.row = gboxpos[0];p os_dir_pair.col = gboxpos[1];p os_dir_pair.dir_from_Pre = 255; Q.push (pos_dir_pair); int people_x = Gpeoplepos[0];int people_y = Gpeoplepos[1];int box_x, box_y, Dir_from_pre, Box_next_ X, Box_next_y, people_next_x, People_next_y;while (! Q.empty ()) {Pos_dir_pair = Q.front (); Q.pop (); box_x = pos_dir_pair.row;box_y = Pos_dir_pair.col;dir_from_pre = pos_dir_pair.dir_from_pre;if (box_x = = Gtargetpos[0] && box_y = = Gtargetpos[1]) {setnodestack (); Movebox ();p rintf ("\ n"); return;} if (dir_from_pre! = 255) {people_x = box_x-gmoveinc[dir_from_pre][0];p eople_y = box_y-gmoveinc[dir_from_pre][1];} else{people_x = gpeoplepos[0];p eople_y = gpeoplepos[1];} for (int i = 1; I <= 4; i++) {//initial dir is illegal, 255box_next_x = box_x + gmoveinc[i][0];box_next_y = box_y + gmoveinc[i][1]; Pre_row is not 0, indicating Point box_next_x, Box_next_y has been entered from the I direction if (gcastle[box_next_x][box_next_y] = = ' # ' | | gpushnodes[box_next_x] [Box_next_y] [I].pre_row) {continue;} people_next_x = box_x-gmoveinc[i][0];p eople_next_y = box_y-gmoveinc[i][1];if (! Canpushfrompos (people_next_x, People_next_y, people_x, people_y, box_x, box_y)) {continue;} Gpushnodes[box_next_x][box_next_y][i].pre_row = Box_x;gpushnodes[box_next_x][box_next_y][i].pre_col = box_y;// Log down the point of the turn before the turn of the direction if (Gpushnodes[box_x][box_y][i].pre_row = = 0) {Gpushnodes[box_x][box_y][i].pre_dir = Dir_from_pre;} Pos_dir_pair. SetInfo (box_next_x, box_next_y, i); Q.push (Pos_dir_pair);}} printf ("impossible.\n\n");} int main () {int cases = 1;while (true) {scanf ("%d%d", &grow, &gcol); if (GRow = = 0) {break;} Input (); Solve (cases + +);} return 0;}
poj_1475 BFS+BFS