1.http://acm.hdu.edu.cn/showproblem.php?pid=1254    推箱子问题

分析:由于箱子每次都只能推,而不能拉,所以我们知道,每次往方向 i 推的时候,人必然会站在一个确切的位置 p 。所以我们在每次推箱子的时候先bfs求出人是否可以到达 p 位置。若可以到达 p ,则往 p 的对面的推动一格,否则判断下一个方向。直到推到目标位置为止。然后我们得到下面的代码:

  1 //First Edit Time:    2014-11-02 17:06
  2 //Last Edit Time:    2014-11-02 18:20
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <queue>
  6 using namespace std;
  7 
  8 struct Pos
  9 {
 10     int bx, by;
 11     int px, py;
 12     int step;
 13 }Box, Person;
 14 
 15 int map[10][10], n, m;
 16 bool used[10][10][10][10];
 17 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
 18 bool visited[10][10];
 19 
 20 bool Judge_Person (Pos a)
 21 {
 22     if(a.px<0 || a.px>m-1 || a.py<0 || a.py>n-1 || visited[a.px][a.py]
 23             || map[a.px][a.py]==1 || (a.px==Box.bx && a.py==Box.by))
 24         return false;
 25     return true;
 26 }
 27 
 28 bool Judge_Box (Pos a)
 29 {
 30     if(a.bx<0 || a.bx>m-1 || a.by<0 || a.by>n-1 || used[a.bx][a.by][Person.px][Person.py] || map[a.bx][a.by]==1)
 31         return false;
 32     return true;
 33 }
 34 
 35 Pos Find_p (Pos a, int i)
 36 {
 37     Pos P = a;
 38     if (i==0)
 39     {
 40         P.px = a.bx + dir[1][0];
 41         P.py = a.by + dir[1][1];
 42     }
 43     else if (i==1)
 44     {
 45         P.px = a.bx + dir[0][0];
 46         P.py = a.by + dir[0][1];
 47     }
 48     else if (i==2)
 49     {
 50         P.px = a.bx + dir[3][0];
 51         P.py = a.by + dir[3][1];
 52     }
 53     else if (i==3)
 54     {
 55         P.px = a.bx + dir[2][0];
 56         P.py = a.by + dir[2][1];
 57     }
 58     return P;
 59 }
 60 
 61 //
 62 bool bfs_person (Pos a)
 63 {
 64     memset (visited, 0, sizeof visited);
 65     if (!Judge_Person (a)) return false;
 66 
 67     Pos Pre, Cur;
 68     queue <Pos> Q;
 69     visited[Person.px][Person.py] = true;
 70 
 71     Q.push (Person);
 72     while (!Q.empty())
 73     {
 74         Pre = Q.front();
 75         Q.pop();
 76         for (int i=0; i<4; i++)
 77         {
 78             Cur.px = Pre.px + dir[i][0];
 79             Cur.py = Pre.py + dir[i][1];
 80             if (Judge_Person (Cur))
 81             {
 82                 visited[Cur.px][Cur.py] = true;
 83                 if (Cur.px==a.px && Cur.py==a.py)
 84                     return true;
 85                 Q.push (Cur);
 86             }
 87         }
 88     }
 89     return false;
 90 }
 91 
 92 int bfs_box ()
 93 {
 94     Pos Pre, Cur, P;
 95     queue <Pos> Q;
 96     memset (used, 0, sizeof used);
 97 
 98     used[Box.bx][Box.by][Person.px][Person.py] = true;
 99     Q.push (Box);
100     while (!Q.empty ())
101     {
102         Pre = Q.front ();
103         Q.pop();
104         for (int i=0; i<4; i++)
105         {
106             Box = Pre;
107 
108             //找到推箱子的位置
109             P = Find_p (Pre, i);
110             
111             if (bfs_person (P))
112             {
113                 Cur = Pre;
114                 Person = P;
115                 Cur.bx += dir[i][0];
116                 Cur.by += dir[i][1];
117                 Cur.step += 1;
118                 if (Judge_Box (Cur))
119                 {
120                     used[Cur.bx][Cur.by][Person.px][Person.py] = true;
121                     if (map[Cur.bx][Cur.by]==3)
122                         return Cur.step;
123                     Q.push (Cur);
124                 }
125             }
126         }
127     }
128     return -1;
129 }
130 
131 int main ()
132 {
133     int t;
134     freopen ("test.in","r",stdin);
135     scanf ("%d",&t);
136     while (t--)
137     {
138         scanf ("%d%d",&m, &n);
139         for (int i=0; i<m; i++)
140             for (int j=0; j<n; j++)
141             {
142                 scanf ("%d",map[i]+j);
143                 if (map[i][j]==2)
144                     Box.bx=i, Box.by=j, Box.step=0;
145                 else if (map[i][j]==4)
146                     Person.px = i,Person.py = j;
147             }
148         int ans = bfs_box ();
149         printf ("%d\n",ans);
150     }
151     return 0;
152 }
View Code

相关文章: