zoukankan      html  css  js  c++  java
  • poj 1475 || zoj 249 Pushing Boxes

    http://poj.org/problem?id=1475

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=249

    Pushing Boxes
    Time Limit: 2000MS   Memory Limit: 131072K
    Total Submissions: 4662   Accepted: 1608   Special Judge

    Description

    Imagine you are standing inside a two-dimensional maze composed of square cells which may or may not be filled with rock. You can move north, south, east or west one cell at a step. These moves are called walks. 
    One of the empty cells contains a box which can be moved to an adjacent free cell by standing next to the box and then moving in the direction of the box. Such a move is called a push. The box cannot be moved in any other way than by pushing, which means that if you push it into a corner you can never get it out of the corner again. 

    One of the empty cells is marked as the target cell. Your job is to bring the box to the target cell by a sequence of walks and pushes. As the box is very heavy, you would like to minimize the number of pushes. Can you write a program that will work out the best such sequence? 

    Input

    The input contains the descriptions of several mazes. Each maze description starts with a line containing two integers r and c (both <= 20) representing the number of rows and columns of the maze. 

    Following this are r lines each containing c characters. Each character describes one cell of the maze. A cell full of rock is indicated by a `#' and an empty cell is represented by a `.'. Your starting position is symbolized by `S', the starting position of the box by `B' and the target cell by `T'. 

    Input is terminated by two zeroes for r and c. 

    Output

    For each maze in the input, first print the number of the maze, as shown in the sample output. Then, if it is impossible to bring the box to the target cell, print ``Impossible.''. 

    Otherwise, output a sequence that minimizes the number of pushes. If there is more than one such sequence, choose the one that minimizes the number of total moves (walks and pushes). If there is still more than one such sequence, any one is acceptable. 

    Print the sequence as a string of the characters N, S, E, W, n, s, e and w where uppercase letters stand for pushes, lowercase letters stand for walks and the different letters stand for the directions north, south, east and west. 

    Output a single blank line after each test case. 

    Sample Input

    1 7
    SB....T
    1 7
    SB..#.T
    7 11
    ###########
    #T##......#
    #.#.#..####
    #....B....#
    #.######..#
    #.....S...#
    ###########
    8 4
    ....
    .##.
    .#..
    .#..
    .#.B
    .##S
    ....
    ###T
    0 0

    Sample Output

    Maze #1
    EEEEE
    
    Maze #2
    Impossible.
    
    Maze #3
    eennwwWWWWeeeeeesswwwwwwwnNN
    
    Maze #4
    swwwnnnnnneeesssSSS

    分析:
    第一次看到题目的时候,以为可以两次bfs,先拿箱子bfs目标,记录路径,得到箱子的开始状态(即人的最终状态),然后再次拿人BFS箱子的初试状态,记录路径,把两个路径加起来即可(之前竟然不知道这个叫嵌套BFS)。
    有几个细节需要注意:
        1,箱子移动时,箱子可以移动到人当前所在的位置。
        2,人移动时,人不能移动到箱子未改变状态时所在的位置。
    后来第三组数据不对,想到了箱子是不能像人一样拐弯的,Orz

    WA代码:

      1 #include <stdio.h>
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <string.h>
      5 #include <string>
      6 #include <math.h>
      7 #include <stdlib.h>
      8 #include <queue>
      9 #include <stack>
     10 #include <set>
     11 #include <map>
     12 #include <list>
     13 #include <iomanip>
     14 #include <vector>
     15 #pragma comment(linker, "/STACK:1024000000,1024000000")
     16 #pragma warning(disable:4786)
     17 
     18 using namespace std;
     19 
     20 const int INF = 0x3f3f3f3f;
     21 const int MAX = 20 + 2;
     22 const double eps = 1e-8;
     23 const double PI = acos(-1.0);
     24 
     25 char ma[MAX][MAX];
     26 int vis[MAX][MAX];
     27 int n , m;
     28 int si , sj , bi , bj , ti , tj , ei , ej;
     29 int dir[4][2] = {1 , 0 , -1 , 0 , 0 , 1 , 0 , -1};
     30 char path[4] = {'S' , 'N' , 'E' , 'W'};
     31 char path1[4] = {'s' , 'n' , 'e' , 'w'};
     32 string str , str1 , ans;
     33 
     34 struct T
     35 {
     36     int x , y ;
     37     string sss;
     38 }temp , in , out;
     39 
     40 queue<T>qq , qq1;
     41 
     42 void bfs(int i , int j)
     43 {
     44     temp.x = i;
     45     temp.y = j;
     46     temp.sss = "";
     47     qq.push(temp);
     48     vis[i][j] = 1;
     49     while(!qq.empty())
     50     {
     51         out = qq.front();
     52         qq.pop();
     53         if(out.x == ti && out.y == tj)
     54         {
     55             str = out.sss;
     56             break;
     57         }
     58         for(int k = 0;k < 4;k ++)
     59         {
     60             int ix = out.x + dir[k][0];
     61             int iy = out.y + dir[k][1];
     62             if(ma[ix][iy] == '#' || vis[ix][iy] || ix < 1 || iy < 1 || ix > n || iy > m)
     63                 continue;
     64             in.x = ix;
     65             in.y = iy;
     66             in.sss = out.sss + path[k];
     67             vis[ix][iy] = 1;
     68             qq.push(in);
     69         }
     70     }
     71 }
     72 
     73 void bfs1(int i , int j)
     74 {
     75     temp.x = i;
     76     temp.y = j;
     77     temp.sss = "";
     78     qq.push(temp);
     79     vis[i][j] = 1;
     80     while(!qq.empty())
     81     {
     82         out = qq.front();
     83         qq.pop();
     84         if(out.x == ei && out.y == ej)
     85         {
     86             str1 = out.sss;
     87             break;
     88         }
     89         for(int k = 0;k < 4;k ++)
     90         {
     91             int ix = out.x + dir[k][0];
     92             int iy = out.y + dir[k][1];
     93             if(ma[ix][iy] == '#' || ma[ix][iy] == 'B' || vis[ix][iy] || ix < 1 || iy < 1 || ix > n || iy > m)
     94                 continue;
     95             in.x = ix;
     96             in.y = iy;
     97             in.sss = out.sss + path1[k];
     98             vis[ix][iy] = 1;
     99             qq.push(in);
    100         }
    101     }
    102 }
    103 
    104 int main()
    105 {
    106     int first = 1;
    107     while(scanf("%d %d",&n , &m) , n + m)
    108     {
    109         int i , j;
    110         memset(vis , 0 , sizeof(vis));
    111         for(i = 1;i <= n;i ++)
    112         {
    113             for(j = 1;j <= m;j ++)
    114             {
    115                 scanf("%c",&ma[i][j]);
    116                 if(ma[i][j] == 'S')
    117                 {
    118                     si = i;
    119                     sj = j;
    120                 }
    121                 else if(ma[i][j] == 'B')
    122                 {
    123                     bi = i;
    124                     bj = j;
    125                 }
    126                 else if(ma[i][j] == 'T')
    127                 {
    128                     ti = i;
    129                     tj = j;
    130                 }
    131             }
    132             getchar();
    133         }
    134         str = "";
    135         while(!qq.empty())
    136             qq.pop();
    137         bfs(bi , bj);
    138         if(str[0] == 'S')
    139         {
    140             ei = bi - 1;
    141             ej = bj;
    142         }
    143         else if(str[0] == 'N')
    144         {
    145             ei = bi + 1;
    146             ej = bj;
    147         }
    148         else if(str[0] == 'E')
    149         {
    150             ei = bi;
    151             ej = bj - 1;
    152         }
    153         else if(str[0] == 'W')
    154         {
    155             ei = bi;
    156             ej = bj + 1;
    157         }
    158 
    159         memset(vis , 0 , sizeof(vis));
    160         str1 = "";
    161         while(!qq.empty())
    162             qq.pop();
    163         bfs1(si , sj);
    164         ans = "";
    165         ans = str1 + str;
    166 
    167         printf("Maze #%d
    ",first ++);
    168         if(ans != "")
    169             cout << ans << "
    " << endl;
    170         else
    171             cout << "Impossible
    " << endl;
    172     }
    173     return 0;
    174 }
    View Code

    后来搜了一些资料。

    双重bfs:

      在推箱子游戏中人推箱子只有两种情况:

        人推箱子:那么箱子此时所处的位置就是人接下来会到达的位置

        人找位子推箱子:那么人就要到达箱子下一步到达位子对应的相反方向得那一个格子

      所以,主干是箱子的移动过程,箱子每移动一步就对接下来人所处的位子进行考虑。也就是在一次bfs的过程中不断套用另一个bfs

    AC代码:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <string>
      5 #include <queue>
      6 using namespace std;
      7 
      8 const int maxn = 22;
      9 char map[maxn][maxn];
     10 bool visPerson[maxn][maxn];
     11 bool visBox[maxn][maxn];
     12 
     13 int R , C;
     14 int dir[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
     15 char pushes[4] = { 'E','W','S','N' };
     16 char walks[4] = { 'e','w','s','n' };
     17 string path;
     18 struct Node
     19 {
     20     int br , bc , pr , pc;
     21     string ans;
     22 };
     23 bool inMap(int r , int c)
     24 {
     25     return r>=0 && r<R && c>=0 && c<C;
     26 }
     27 bool bfs2(int sr, int sc, int er, int ec, int br, int bc, string &ans)
     28 {
     29     Node node , tmpnode;
     30     memset(visPerson,0,sizeof(visPerson));
     31     queue<Node> Q;
     32     node.pr = sr;
     33     node.pc = sc;
     34     node.ans = "";
     35     Q.push(node);
     36     visPerson[br][bc] = true;
     37     while(!Q.empty()) {
     38         node = Q.front();  Q.pop();
     39         if(node.pr == er && node.pc == ec) {
     40             ans = node.ans;
     41             return true;
     42         }
     43         if(visPerson[node.pr][node.pc]) continue;
     44         visPerson[node.pr][node.pc] = true;
     45         for(int i=0;i<4;i++) {
     46             int nr = node.pr + dir[i][0];
     47             int nc = node.pc + dir[i][1];
     48             if(inMap(nr,nc) && !visPerson[nr][nc] && map[nr][nc]!='#') {
     49                 tmpnode.pr = nr;
     50                 tmpnode.pc = nc;
     51                 tmpnode.ans =node.ans + walks[i];
     52                 Q.push(tmpnode);
     53             }
     54         }
     55     }
     56     return false;
     57 }
     58 bool bfs1(int sr ,int sc, int br, int bc) {
     59     Node node , tmpnode;
     60     memset(visBox,0,sizeof(visBox));
     61     queue<Node> Q;
     62     node.pr = sr;
     63     node.pc = sc;
     64     node.br = br;
     65     node.bc = bc;
     66     node.ans = "";
     67     Q.push(node);
     68     while(!Q.empty()) {
     69         node = Q.front();  Q.pop();
     70         if(visBox[node.br][node.bc])
     71             continue;
     72         visBox[node.br][node.bc] = true;
     73         if(map[node.br][node.bc]=='T') {
     74             path = node.ans;
     75             return true;
     76         }
     77         visBox[node.br][node.bc] = true;
     78         for(int i=0;i<4;i++) {
     79             int nextr = node.br + dir[i][0];
     80             int nextc = node.bc + dir[i][1];
     81             int backr = node.br - dir[i][0];
     82             int backc = node.bc - dir[i][1];
     83             string ans = "";
     84             if( inMap(nextr,nextc) && inMap(backr,backc)
     85             && map[nextr][nextc]!='#' && map[backr][backc]!='#'
     86             && !visBox[nextr][nextc] ) {
     87                 if(bfs2(node.pr, node.pc, backr, backc, node.br, node.bc, ans)) {
     88                     tmpnode.pr = node.br;
     89                     tmpnode.pc = node.bc;
     90                     tmpnode.br = nextr;
     91                     tmpnode.bc = nextc;
     92                     tmpnode.ans = node.ans +ans +pushes[i];
     93                     Q.push(tmpnode);
     94                 }
     95             }
     96         }
     97     }
     98     return false;
     99 }
    100 int main() {
    101     int cas = 1;
    102     int sr , sc , br , bc;
    103     while(~scanf("%d%d",&R,&C) && R) {
    104         for(int i=0;i<R;i++) scanf("%s",map[i]);
    105         for(int i=0;i<R;i++)
    106             for(int j=0;j<C;j++) {
    107                 if(map[i][j]=='S') {
    108                     sr = i; sc = j;
    109                 }
    110                 if(map[i][j]=='B') {
    111                     br = i; bc = j;
    112                 }
    113             }
    114         path = "";
    115         printf("Maze #%d
    ",cas++);
    116         bfs1(sr,sc,br,bc) ? cout<<path<<endl : cout<<"Impossible."<<endl;
    117         cout<<endl;
    118     }
    119     return 0;
    120 }
    View Code

    后来测试了几组数据:发现有些数据过不了(比如下面的数据),oj数据水呀。

    1 8 9
    2 #########
    3 #......T#
    4 #.S.....#
    5 ##B######
    6 #.......#
    7 #.......#
    8 #.......#
    9 #########
    View Code

    以箱子为开始点 进行BFS。每次判断人(BFS)能不能到达箱子所需推到的反方向。如果能救如队列。有几个细节需要注意。1,箱子移动时,箱子可以移动到人当前所在的位置。2,人移动时,人不能移动到箱子未改变状态时所在的位置。。然后模拟即可。

    AC代码:

      1 #include<iostream>
      2 #include<vector>
      3 #include<cstdio>
      4 #include<string>
      5 #include<queue>
      6 #include<cstring>
      7 using namespace std;
      8 int n,m;
      9 char map[25][25];
     10 int       dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
     11 int other_dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
     12 int ex,ey,flag;
     13 bool vis[25][25][25][25];
     14 bool mark[25][25];
     15 char op[]="nswe";
     16 char big_op[]="NSWE";
     17 string ans;
     18 struct node{
     19     int b_x,b_y;
     20     int p_x,p_y;
     21     int step;
     22     string ans;
     23 }s_pos;
     24 bool cheack(int x,int y){
     25      return x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='#';
     26      return false;
     27 }
     28 bool people_cango(node &cur,node last,int e_x,int e_y){
     29      queue<node > q;  node per;per=cur;   per.step=0;  per.ans="";
     30      memset(mark,false,sizeof(mark));
     31      q.push(per);
     32      mark[cur.p_x][cur.p_y]=true;
     33 
     34      while(!q.empty()){
     35          node now=q.front();  q.pop();
     36           if(now.p_x==e_x&&now.p_y==e_y){
     37              cur.ans+=now.ans;
     38              return true;
     39            }
     40          for(int i=0;i<4;i++){
     41              node next=now;     next.step+=1;
     42              next.p_x+=dir[i][0];   next.p_y+=dir[i][1];
     43              if(cheack(next.p_x,next.p_y)&&!mark[next.p_x][next.p_y]){
     44                  if(next.p_x==last.b_x&&next.p_y==last.b_y)  continue;  //遇见箱子
     45                  mark[next.p_x][next.p_y]=true;
     46                  next.ans+=op[i];
     47                  if(next.p_x==e_x&&next.p_y==e_y){
     48                     cur.ans+=next.ans;
     49                     return true;
     50                  }
     51                  q.push(next);
     52              }
     53          }
     54      }
     55     return false;
     56 
     57 }
     58 void bfs(){
     59      queue<node > q;
     60      memset(vis,false,sizeof(vis));     q.push(s_pos);
     61      vis[s_pos.b_x][s_pos.b_y][s_pos.p_x][s_pos.p_y]=true;
     62      while(!q.empty()){
     63          node now = q.front(); q.pop();
     64 
     65          for(int i=0;i<4;i++){
     66              node next = now;   next.step+=1;
     67              next.b_x+=dir[i][0];  next.b_y+=dir[i][1];
     68 
     69              int x=now.b_x+other_dir[i][0];                  //人要到达箱子的反面
     70              int y=now.b_y+other_dir[i][1];
     71              if(cheack(next.b_x,next.b_y)&&cheack(x,y)&&!vis[next.b_x][next.b_y]
     72                 [now.b_x][now.b_y]){
     73             //     if(next.b_x==now.p_x&&next.b_y==now.p_y)  continue;
     74               //    cout<<next.p_x<<" "<<next.p_y<<endl;
     75 
     76                  if(people_cango(next,now,x,y)){
     77               //      cout<<x<<" "<<y<<endl;
     78                     next.p_x=now.b_x;
     79                     next.p_y=now.b_y;
     80                     next.ans+=big_op[i];
     81                      if(next.b_x==ex&&next.b_y==ey){
     82                         flag=1;
     83                         ans=next.ans;
     84                         return ;
     85                     }
     86 
     87                     vis[next.b_x][next.b_y][next.p_x][next.p_y]=true;
     88                     q.push(next);
     89                  }
     90              }
     91 
     92 
     93          }
     94 
     95      }
     96 
     97 }
     98 int main(){
     99     int ca=1;
    100     while(scanf("%d%d",&n,&m)!=EOF,n+m){
    101 
    102           for(int i=0;i<n;i++)  scanf("%s",map[i]);
    103 
    104           for(int i=0;i<n;i++){
    105               for(int j=0;j<m;j++){
    106               if(map[i][j]=='T'){
    107                   ex=i,ey=j;
    108               }
    109               if(map[i][j]=='B'){
    110                   s_pos.b_x=i;  s_pos.b_y=j;
    111               }
    112               if(map[i][j]=='S'){
    113                   s_pos.p_x=i;  s_pos.p_y=j;
    114               }
    115               }
    116           }
    117           
    118 
    119           flag=0; s_pos.step=0;  s_pos.ans="";
    120           bfs();
    121           cout<<"Maze #"<<ca++<<endl;
    122           if(flag){
    123              cout<<ans<<endl;
    124           }
    125           else
    126           cout<<"Impossible."<<endl;
    127           cout<<endl;
    128           
    129 
    130     }
    131     return 0;
    132 }
    View Code

    AC代码: 

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 #include <queue>
      6 #include <string>
      7 
      8 using namespace std;
      9 
     10 #define MAXN 22
     11 char P[4]={'N','S','W','E'};
     12 char M[4]={'n','s','w','e'};
     13 int R,C;
     14 int dir[4][2]={-1,0,1,0,0,-1,0,1};
     15 char map[MAXN][MAXN];
     16 struct point
     17 {
     18     int x,y;
     19     int p_x,p_y;//当前状态person所在的地方
     20     string ans;
     21 };
     22 bool isok(int x,int y)
     23 {
     24     if(x>=0 && x<R && y>=0 && y<C && map[x][y] != '#')
     25         return true;
     26     return false;
     27 }
     28 string tmp;
     29 bool bfs_person(point en,point cu)
     30 {
     31     tmp="";
     32     point st;
     33     st.x=en.p_x;
     34     st.y=en.p_y;
     35     st.ans="";
     36     queue<point>q;
     37     bool vis[MAXN][MAXN];
     38     memset(vis,0,sizeof(vis));
     39     while(!q.empty())
     40         q.pop();
     41     q.push(st);
     42     while(!q.empty())
     43     {
     44         point cur,next;
     45         cur=q.front();
     46         q.pop();
     47         if(cur.x==en.x && cur.y==en.y)
     48         {
     49             tmp=cur.ans;
     50             return true;
     51         }
     52         for(int i=0;i<4;i++)
     53         {
     54             next=cur;
     55             next.x=cur.x+dir[i][0];
     56             next.y=cur.y+dir[i][1];
     57             if(!isok(next.x,next.y)) continue;
     58             if(next.x==cu.x && next.y==cu.y) continue;
     59             if(vis[next.x][next.y]) continue;
     60             vis[next.x][next.y]=1;
     61             next.ans=cur.ans+M[i];
     62             q.push(next);
     63         }
     64     }
     65     return false;
     66 }
     67 string bfs_box()
     68 {
     69     bool vis[MAXN][MAXN][4];//某点四个方向是否访问!!0==N,1==S,2==W,3==E
     70     point st;
     71     st.x=st.y=-1;
     72     st.p_x=st.p_y=-1;
     73     st.ans="";
     74     for(int i=0;i<R && (st.x==-1 || st.p_x==-1);i++)
     75         for(int j=0;j<C && (st.x==-1 || st.p_x==-1);j++)
     76             if(map[i][j]=='B')
     77             {
     78                 st.x=i;
     79                 st.y=j;
     80                 map[i][j]='.';
     81             }
     82             else if(map[i][j]=='S')
     83             {
     84                 st.p_x=i;
     85                 st.p_y=j;
     86                 map[i][j]='.';
     87             }
     88     //----------------------------------------
     89     //cout<<"st.x="<<st.x<<" st.y="<<st.y<<" st.p_x="<<st.p_x<<" st.p_y="<<st.p_y<<endl;
     90     //----------------------------------------
     91     queue<point> q;
     92     while(!q.empty())
     93         q.pop();
     94     q.push(st);
     95     memset(vis,0,sizeof(vis));
     96     while(!q.empty())
     97     {
     98         point cur=q.front();q.pop();    
     99         //----------------------------------------
    100     //        cout<<"cur.x="<<cur.x<<" cur.y="<<cur.y<<" cur.p_x="<<cur.p_x<<" cur.p_y="<<cur.p_y<<endl;
    101     //    cout<<"-----------------------------
    ";
    102         //----------------------------------------
    103         point next,pre;
    104         if(map[cur.x][cur.y]=='T')
    105             return cur.ans;
    106         for(int i=0;i<4;i++)
    107         {
    108             next=cur;
    109             next.x=cur.x+dir[i][0];
    110             next.y=cur.y+dir[i][1];
    111             if(!isok(next.x,next.y))
    112                 continue;
    113             if(vis[next.x][next.y][i])
    114                 continue;
    115             pre=cur;
    116             switch(i)
    117             {
    118                 case 0: pre.x=cur.x+1;break;
    119                 case 1: pre.x=cur.x-1;break;
    120                 case 2: pre.y=cur.y+1;break;
    121                 case 3: pre.y=cur.y-1;break;
    122             }
    123             if(!bfs_person(pre,cur))//搜寻人是否能走到特定的位置
    124                 continue;
    125             vis[next.x][next.y][i]=1;
    126             next.ans=cur.ans+tmp;
    127             next.ans=next.ans+P[i];
    128             next.p_x=cur.x;next.p_y=cur.y;
    129             q.push(next);
    130         }
    131     }
    132     return "Impossible.";
    133 }
    134 
    135 int main()
    136 {
    137     int cas=1;
    138     while(scanf("%d%d",&R,&C) && (R+C))
    139     {
    140         getchar();
    141         for(int i=0;i<R;i++)
    142             gets(map[i]);
    143 
    144         //---------------------------------------
    145     //    for(int i=0;i<R;i++)
    146         //    cout<<map[i]<<endl;
    147         //----------------------------------------
    148 
    149         printf("Maze #%d
    ",cas++);
    150         //printf("%s
    ",bfs_box());
    151         cout<<bfs_box()<<endl<<endl;
    152     }
    153     return 0;
    154 }
    View Code

    程序终究是会有bug,上面两个肯定也有bug数据过不了,就不列举啦,重要是思想。

    下面一个是wcg的AC代码:

    附上链接:http://www.cnblogs.com/lovychen/p/4453147.html

      1 //解题思路:先判断盒子的四周是不是有空位,如果有,则判断人是否能到达盒子的那一边,能的话,把盒子推到空位处,然后继续
      2 #include<iostream>
      3 #include<algorithm>
      4 #include<cstdio>
      5 #include<cstring>
      6 #include<queue>
      7 #include<string>
      8 #include<cmath>
      9 using namespace std;
     10 int bx,by,sx,sy,tx,ty;
     11 int m,n,dir[][2]={-1,0,1,0,0,-1,0,1};//注意题目要求的是n、s、w、e的顺序,因为这个wa了一次
     12 char op[]={'n','s','w','e'};
     13 bool mark[25][25][4];//标记箱子四周的位置时候已被用过
     14 int vis[25][25];//标记人走过的位置
     15 char  map[25][25];
     16 struct BB//盒子
     17 {
     18     int x,y,SX,SY;//SX,SY表示当前箱子固定了,人所在的位置
     19     string ans;
     20 }bnow,beed;
     21 struct YY//
     22 {
     23     int x,y;
     24     string ans;
     25 }ynow,yeed;
     26 char up(char c)
     27 {
     28     return (c-'a'+'A');
     29 }
     30 //aa,bb 表示当前盒子的位置;ss,ee表示起点;
     31 bool bfs2(int s,int e,int aa,int bb,int ss,int ee)//寻找当前人,是否能够到达盒子指定的位置;
     32 {
     33     queue<YY>yy;
     34     if(s<0 || s>m || e<0 || e>n || map[s][e] == '#') return false;
     35     ynow.x = ss; ynow.y = ee; ynow.ans="";
     36     memset(vis,0,sizeof(vis));
     37     vis[aa][bb] =1;//不能经过盒子
     38     vis[ss][ee] = 1;//起点标记为
     39     yy.push(ynow);
     40     while(!yy.empty())
     41     {
     42         ynow = yy.front();
     43         yy.pop();
     44         if(ynow.x == s && ynow.y == e)
     45         {
     46             return true;
     47         }
     48         for(int i=0;i<4;i++)
     49         {
     50             yeed.x = ynow.x+dir[i][0];
     51             yeed.y = ynow.y+dir[i][1];
     52             if(yeed.x>0 && yeed.x<=m && yeed.y>0 && yeed.y<=n && !vis[yeed.x][yeed.y] && map[yeed.x][yeed.y]!='#')
     53             {
     54                 yeed.ans = ynow.ans+op[i];//记录走过的路径
     55                 vis[yeed.x][yeed.y] = 1;
     56                 yy.push(yeed);
     57             }
     58         }
     59     }
     60     return false;
     61 }
     62 
     63 bool bfs1()
     64 {
     65    queue<BB>bb;
     66    bnow.x = bx;bnow.y=by;bnow.ans="";
     67    bnow.SX = sx;bnow.SY=sy;
     68    bb.push(bnow);
     69    while(!bb.empty())
     70    {
     71 
     72        bnow=bb.front();
     73        bb.pop();
     74        if(bnow.x == tx && bnow.y==ty)
     75        {
     76            return true;
     77        }
     78        for(int i=0;i<4;i++) //盒子周围的四个方向;
     79        {
     80            beed.x = bnow.x+dir[i][0];
     81            beed.y = bnow.y+dir[i][1];
     82            if(beed.x>0 && beed.x<=m && beed.y>0 && beed.y<=n && !mark[beed.x][beed.y][i] && map[beed.x][beed.y]!='#')
     83            {
     84                if(bfs2(beed.x-2*dir[i][0],beed.y-2*dir[i][1],bnow.x,bnow.y,bnow.SX,bnow.SY))//如果能推到yeed,则需要判断人是否能到达,它的上一个点;
     85                {
     86                     beed.SX = bnow.x;//推完箱子后,人的位置在箱子上
     87                     beed.SY = bnow.y;
     88                     beed.ans=bnow.ans+ynow.ans+up(op[i]);//当前的加上推箱子的加上目前挨着推的;
     89                     mark[beed.x][beed.y][i] = true;
     90                     bb.push(beed);
     91                }
     92            }
     93        }
     94      }
     95    return false;
     96 }
     97 
     98 int main()
     99 {
    100     int T,k=1;
    101     while(scanf("%d %d",&m,&n) && m+n)
    102     {
    103         memset(mark,false,sizeof(mark));
    104         for(int i=1;i<=m;i++)
    105             for(int j=1;j<=n;j++)
    106             {
    107                 scanf(" %c",&map[i][j]);
    108                 if(map[i][j] == 'S')
    109                 {
    110                     sx=i;sy =j;
    111                 }
    112                 if(map[i][j] == 'T')
    113                 {
    114                     tx = i;ty = j;
    115                 }
    116                 if(map[i][j] == 'B')
    117                 {
    118                     bx = i;by = j;
    119                 }
    120             }
    121         printf("Maze #%d
    ",k++);
    122             if(bfs1())
    123                 printf("%s
    
    ",bnow.ans.c_str());//少个换行wa了一次
    124             else
    125                 printf("Impossible.
    
    ");
    126     }
    127     return 0;
    128 }
    View Code
  • 相关阅读:
    Kubernetes Python Client 初体验之安装授权
    用Ubuntu和树莓派系统部署kubernetes集群后的一些心得
    OpenWrt下基于OLSR的Ad-Hoc组网实现网络摄像头多节点访问
    KVM初体验之virt-manager unable to connect to libvirt的处理办法
    oracle参数和日志文件
    trigger
    package
    function
    procedure
    oracle异常处理
  • 原文地址:https://www.cnblogs.com/jeff-wgc/p/4451932.html
Copyright © 2011-2022 走看看