zoukankan      html  css  js  c++  java
  • poj 1475 推箱子

    bfs是一层层的遍历下去,每多一层即为多走一步,因此只要遇到T就停,此时肯定是最小步数。

    所以这两层bfs应为,先对箱子的最少步数进行bfs,从而求出推箱子所用最少步数;

    然后箱子bfs内部嵌入人的bfs,从而箱子每走一步,判断一下这个移动能否由人来完成(由箱子的移动倒推人应该在的位置,看这个位置是否合理)。

    一、http://tech.artyoo.me/?p=282

      1 #include <map>
      2 #include <set>
      3 #include <queue>
      4 #include <stack>
      5 #include <math.h>
      6 #include <time.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <iostream>
     10 #include <limits.h>
     11 #include <string.h>
     12 #include <string>
     13 #include <algorithm>
     14 #include <iomanip>
     15 #define read freopen("in.txt","r",stdin)  
     16 #define write freopen("out.txt","w",stdout) 
     17 using namespace std;
     18 #define MAXSIZE 22
     19 typedef struct {
     20     int bx, by, px, py;
     21     string path;
     22 } Node;
     23 typedef struct {
     24     int x, y;
     25     string path;    
     26 } Point;
     27 int row, col;
     28 char grid[MAXSIZE][MAXSIZE];
     29 bool vis[MAXSIZE][MAXSIZE][4], vis2[MAXSIZE][MAXSIZE];
     30 Node st;
     31 int caseID;
     32 queue<Node> qb;
     33 queue<Point> qp;
     34  
     35 const int dx[] = {-1, 1, 0, 0};
     36 const int dy[] = {0, 0, -1, 1};
     37 const char Dir[] = {'N', 'S', 'W', 'E'};
     38 const char dir[] = {'n', 's', 'w', 'e'};
     39 string person_path;
     40  
     41 int Min(int a,int b){return a<b?a:b;}
     42 int Max(int a,int b){return a>b?a:b;}
     43  
     44 bool bfs_person(Point sp, Point ep, int bx, int by) {
     45     person_path = "";
     46     memset(vis2, false, sizeof(vis2));
     47     while(!qp.empty()) qp.pop();
     48     sp.path = "";
     49     qp.push(sp);
     50     vis2[sp.x][sp.y] = true;
     51     while(!qp.empty()) {
     52         Point now = qp.front(); qp.pop();
     53         if(now.x == ep.x && now.y == ep.y) {
     54             person_path = now.path;
     55             return true;
     56         }
     57         for(int d = 0; d < 4; d++) {
     58             int x = now.x + dx[d];
     59             int y = now.y + dy[d];
     60             if(x >= 0 && x < row && y >= 0 && y < col && grid[x][y] != '#' && !(x == bx && y == by)) {
     61                 if(!vis2[x][y]) {
     62                     Point next;
     63                     next.x = x;
     64                     next.y = y;
     65                     next.path = now.path + dir[d];
     66                     qp.push(next);
     67                     vis2[x][y] = true;  
     68                 }  
     69             }
     70         }
     71     }
     72     return false;
     73 }
     74  
     75 string bfs_box() {
     76     memset(vis, false, sizeof(vis));
     77     while(!qb.empty()) qb.pop();
     78     qb.push(st);
     79     while(!qb.empty()) {
     80         Node now;
     81         now = qb.front(); qb.pop();
     82         if(grid[now.bx][now.by] == 'T') {
     83             return now.path;    
     84         }
     85         for(int d = 0; d < 4; d++) {
     86             int x = now.bx + dx[d];
     87             int y = now.by + dy[d];
     88             if(x >= 0 && x < row && y >= 0 && y < col && grid[x][y] != '#') {
     89                 if(!vis[x][y][d]) {
     90                     Point sp, ep; /* sp: 人的当前位置;ep:人要按当前方向推箱子的话必须得到达的位置 */
     91                     sp.x = now.px;  sp.y = now.py;
     92                     ep.x = now.bx;  ep.y = now.by;
     93                     switch(d) {
     94                         case 0: ep.x += 1; break;
     95                         case 1: ep.x -= 1; break;
     96                         case 2: ep.y += 1; break;
     97                         case 3: ep.y -= 1; break; 
     98                     }
     99                     if(ep.x >= 0 && ep.x < row && ep.y >= 0 && ep.y < col && grid[ep.x][ep.y] != '#') {            
    100                         if(bfs_person(sp, ep, now.bx, now.by)) {
    101                             Node next;
    102                             next.bx = x;  next.by = y;
    103                             next.px = now.bx;  next.py = now.by;
    104                             next.path = now.path + person_path + Dir[d];
    105                             qb.push(next);
    106                             vis[x][y][d] = true;
    107                         }
    108                     }
    109                 }
    110             }
    111         }
    112     }
    113     return "Impossible.";
    114 }
    115  
    116 int main() {
    117     read; write;
    118     caseID = 0;
    119     while(scanf("%d%d", &row, &col) && row && col) {
    120         getchar();
    121         for(int i = 0; i < row; i++) {
    122             gets(grid[i]);
    123         }
    124         for(int i = 0; i < row; i++) {
    125             for(int j = 0; j < col; j++) {
    126                 if(grid[i][j] == 'B') {
    127                     st.bx = i;
    128                     st.by = j;
    129                     grid[i][j] = '.';
    130                 } else if(grid[i][j] == 'S') {
    131                     st.px = i;
    132                     st.py = j;
    133                     grid[i][j] = '.';
    134                 }
    135             }
    136         }
    137         st.path = "";
    138         printf("Maze #%d
    ", ++caseID);
    139         cout << bfs_box() << endl << endl;
    140     }
    141     return 0;
    142 }

    二、http://www.cnblogs.com/Missa/archive/2012/10/07/2714435.html

      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 };//之前当成坐标轴里x,y坐标来算,怎么都不对。后来发现原来x,y是行数和列数。x-1代表到上一行去,即N。
     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;//cu.x,cu.y is the location of the box.
     59             if (vis[next.x][next.y]) continue;//来过的地方就不能在来了???????莫非bfs都是这样?
     60             vis[next.x][next.y] = 1;
     61             next.ans = cur.ans + M[i];
     62             //cout << "M[i] "<<M[i] << endl;
     63             //cout << "cur.ans " << cur.ans << endl;
     64             q.push(next);
     65         }
     66     }
     67     return false;
     68 }
     69 string bfs_box()
     70 {
     71     bool vis[MAXN][MAXN][4];//某点四个方向是否访问!!0==N,1==S,2==W,3==E
     72     point st;
     73     st.x = st.y = -1;
     74     st.p_x = st.p_y = -1;
     75     st.ans = "";
     76     for (int i = 0; i < R && (st.x == -1 || st.p_x == -1); i++)
     77     for (int j = 0; j < C && (st.x == -1 || st.p_x == -1); j++)
     78     if (map[i][j] == 'B')
     79     {
     80         st.x = i;
     81         st.y = j;
     82         map[i][j] = '.';
     83     }
     84     else if (map[i][j] == 'S')
     85     {
     86         st.p_x = i;
     87         st.p_y = j;
     88         map[i][j] = '.';
     89     }
     90     //----------------------------------------
     91     //cout<<"st.x="<<st.x<<" st.y="<<st.y<<" st.p_x="<<st.p_x<<" st.p_y="<<st.p_y<<endl;
     92     //----------------------------------------
     93     queue<point> q;
     94     while (!q.empty())
     95         q.pop();
     96     q.push(st);
     97     memset(vis, 0, sizeof(vis));
     98     while (!q.empty())
     99     {
    100         point cur = q.front(); q.pop();
    101         //----------------------------------------
    102         //        cout<<"cur.x="<<cur.x<<" cur.y="<<cur.y<<" cur.p_x="<<cur.p_x<<" cur.p_y="<<cur.p_y<<endl;
    103         //    cout<<"-----------------------------
    ";
    104         //----------------------------------------
    105         point next, pre;
    106         if (map[cur.x][cur.y] == 'T')
    107             return cur.ans;
    108         for (int i = 0; i < 4; i++)
    109         {
    110             next = cur;
    111             next.x = cur.x + dir[i][0];
    112             next.y = cur.y + dir[i][1];
    113             if (!isok(next.x, next.y))
    114                 continue;
    115             if (vis[next.x][next.y][i])
    116                 continue;
    117             pre = cur;
    118             switch (i)
    119             {
    120             case 0: pre.x = cur.x + 1; break;
    121             case 1: pre.x = cur.x - 1; break;
    122             case 2: pre.y = cur.y + 1; break;
    123             case 3: pre.y = cur.y - 1; break;
    124             }
    125             if (!bfs_person(pre, cur))//搜寻人是否能走到特定的位置
    126                 continue;
    127             vis[next.x][next.y][i] = 1;
    128             next.ans = cur.ans + tmp;
    129             next.ans = next.ans + P[i];
    130             cout << "P[i] " << P[i] << endl;
    131             cout <<"cur--"<< cur.x << "," << cur.y << ";" << cur.p_x << "," << cur.p_y << endl;
    132             cout <<"next--" << next.x << "," << next.y << ";" << next.p_x << "," << next.p_y << endl;
    133             next.p_x = cur.x; next.p_y = cur.y;
    134             q.push(next);
    135         }
    136     }
    137     return "Impossible.";
    138 }
    139 
    140 int main()
    141 {
    142     int cas = 1;
    143     while (scanf("%d%d", &R, &C) && (R + C))
    144     {
    145         getchar();
    146         for (int i = 0; i < R; i++)
    147             gets(map[i]);
    148 
    149         //---------------------------------------
    150         //    for(int i=0;i<R;i++)
    151         //    cout<<map[i]<<endl;
    152         //----------------------------------------
    153 
    154         printf("Maze #%d
    ", cas++);
    155         //printf("%s
    ",bfs_box());
    156         cout << bfs_box() << endl << endl;
    157     }
    158     return 0;
    159 }
  • 相关阅读:
    LeetCode My Solution: Minimum Depth of Binary Tree
    Managing Data in Containers
    ZooKeeper系列(四)
    ZooKeeper系列(三)
    ZooKeeper系列(二)
    Zookeeper系列(一)
    (转)淘淘商城系列——dubbo监控中心
    (转)淘淘商城系列——MyBatis分页插件(PageHelper)的使用以及商品列表展示
    (转)淘淘商城系列——展示后台管理页面
    (转)淘淘商城系列——服务调用测试
  • 原文地址:https://www.cnblogs.com/forcheryl/p/4411056.html
Copyright © 2011-2022 走看看