hdu 1254 推箱子 BFS

来源:互联网 发布:unity3d用什么语言 编辑:程序博客网 时间:2024/05/22 03:38

hdu 1254 推箱子 BFS[含测试数据]

题目链接: Here!
思路:每次箱子移动之前,肯定都是人先到达箱子相邻的位置上,然后推动箱子移动一步。比如:箱子现在的位置是(x,y),如果箱子需要向(1,0)方向移动,即箱子要移动到(x+1,y),那么肯定需要先让人移动到(x-1,y)的位置上。如果
这样每次箱子移动一步之前,就需要检查人是不是能够到达与之相邻的位置。
然后需要注意的几点:
  1. BFS需要保存的状态:
    对于人的移动,只需要保存当前移动到的坐标;
    对于箱子的移动,则需要保存当前箱子移动到的坐标与移动的步数, 还有一个就是当前人的位置;
  2. 例如下面的第三组数据,需要注意的是对于箱子的移动的vis数组要开三维的,因为箱子可能经过同一个点多次。
测试数据
4
5 5
3 0 1 0 0
1 0 1 4 0
0 0 1 0 0
1 0 2 0 0
0 0 0 0 0
5 5
0 3 0 0 0
1 0 1 4 0
0 0 1 0 0
1 0 2 0 0
0 0 0 0 0
5 5
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
1 1 2 1 1
4 0 3 0 0
7 4
0 0 0 0
0 0 1 0
0 2 0 3
1 4 1 0
1 0 1 0
1 0 1 0
1 0 0 0
答案应该是:-1 4 5 2
#include <map>#include <vector>#include <queue>#include <cmath>#include <cstdio>#include <string>#include <cstring>#include <iomanip>#include <iostream>#include <algorithm>using namespace std;//#pragma comment(linker, "/STACK:1024000000,1024000000")#define FIN             freopen("input.txt","r",stdin)#define FOUT            freopen("output.txt","w",stdout)#define CASE(T)         for(scanf("%d",&T);T--;)#define fst             first#define snd             second#define lson            l, mid, rt << 1#define rson            mid+1, r, rt << 1 | 1const int MAXN = 7 + 5;//const double eps = 1e-6;const int DIR[][2] = { {0, 1}, {0, -1}, {1, 0}, { -1, 0} };struct NodeP {    int x, y;} cur_p, rear_p;struct NodeB : public NodeP {    int step;    NodeP p_pos;} cur_b, rear_b;int T, N, M;int Gx, Gy;int G[MAXN][MAXN];bool vis_p[MAXN][MAXN];bool vis_b[MAXN][MAXN][4];queue<NodeP> QP;queue<NodeB> QB;inline bool outRange(int x, int y) {    return x < 0 || y < 0 || x >= N || y >= M;}bool BFS_P(int Px, int Py) {    if(outRange(Px, Py)) return false;    int ret = false;    memset(vis_p, false, sizeof(vis_p));    vis_p[cur_p.x][cur_p.y] = true;    QP.push(cur_p);    while(!QP.empty()) {        cur_p = QP.front();        QP.pop();        if(ret) continue;        if(cur_p.x == Px && cur_p.y == Py) {            ret = true;            continue;        }        for(int i = 0; i < 4; i ++) {            rear_p.x = cur_p.x + DIR[i][0];            rear_p.y = cur_p.y + DIR[i][1];            if(outRange(rear_p.x, rear_p.y)) continue;            if(vis_p[rear_p.x][rear_p.y]) continue;            if(G[rear_p.x][rear_p.y] == 1 || (rear_p.x == cur_b.x && rear_p.y == cur_b.y)) continue;            vis_p[rear_p.x][rear_p.y] = true;            QP.push(rear_p);        }    }    return ret;}int BFS_B() {    int ret = -1;    memset(vis_b, false, sizeof(vis_b));    cur_b.step = 0;    cur_b.p_pos = cur_p;    QB.push(cur_b);    while(!QB.empty()) {        cur_b = QB.front();        QB.pop();        if(~ret) continue;        if(cur_b.x == Gx && cur_b.y == Gy) {            ret = cur_b.step;            continue;        }        cur_p = cur_b.p_pos;        for(int i = 0; i < 4; i ++) {            rear_b.x = cur_b.x + DIR[i][0];            rear_b.y = cur_b.y + DIR[i][1];            rear_b.p_pos.x = cur_b.x - DIR[i][0];            rear_b.p_pos.y = cur_b.y - DIR[i][1];            int &Px = rear_b.p_pos.x;            int &Py = rear_b.p_pos.y;            if(outRange(rear_b.x, rear_b.y) || outRange(Px, Py)) continue;            if(vis_b[rear_b.x][rear_b.y][i]) continue;            if(G[rear_b.x][rear_b.y] == 1 || G[Px][Py] == 1) continue;            bool suc = BFS_P(Px, Py);            if(!suc) continue;            rear_b.step = cur_b.step + 1;            vis_b[rear_b.x][rear_b.y][i] = true;            QB.push(rear_b);        }    }    return ret;}int main() {#ifndef ONLINE_JUDGE    FIN;#endif // ONLINE_JUDGE    scanf("%d", &T);    while(T --) {        scanf("%d %d", &N, &M);        for(int i = 0; i < N; i++) {            for(int j = 0; j < M; j++) {                scanf("%d", &G[i][j]);                if(G[i][j] == 2) {                    cur_b.x = i;                    cur_b.y = j;                } else if(G[i][j] == 3) {                    Gx = i;                    Gy = j;                } else if(G[i][j] == 4) {                    cur_p.x = i;                    cur_p.y = j;                }            }        }        int res = BFS_B();        printf("%d\n", res);    }    return 0;}


2 0
原创粉丝点击