zoukankan      html  css  js  c++  java
  • hdu 1732 Push Box (bfs)

    题意:推箱子升级版,将三个箱子推到三个洞里,求最小步骤

    分析:思路不难,就是处理起来,细节太多,纠结死了。一个八维的布尔数组判重,差点就MLE了

    View Code
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #define size 9
    using namespace std;
    struct Node
    {
    int x, y;
    int Box[3][2];//记录三个箱子的位置
    int step;
    char map[size][size];
    } start;
    int dir[4][2] = {{0, -1}, {0, 1}, { -1, 0}, {1, 0}};
    char map[size][size];
    int n, m;
    int T_map[size][size];//临时地图
    bool visit[size][size][size][size][size][size][size][size];//八维数组,状态判重
    Node pre, nex;
    bool is_finish(Node a)//判断是否每个箱子都入洞
    {
    return (map[a.Box[0][0]][a.Box[0][1]] == '@' && map[a.Box[1][0]][a.Box[1][1]] == '@' && map[a.Box[2][0]][a.Box[2][1]] == '@' );
    }
    bool check(int x, int y)
    {
    return (x >= 0 && x < n && y >= 0 && y < m);
    }
    int ans;
    char Tmap[size][size];//临时地图
    void BFS()
    {
    queue <Node> Que;
    memset(visit, false, sizeof(visit));
    Que.push(start);
    while (!Que.empty())
    {
    pre = Que.front();
    Que.pop();
    if (is_finish(pre))
    {
    ans = pre.step;
    return ;
    }
    for (int i = 0; i < 4; i ++)
    {
    //将前一个的地图copy到临时地图中
    memcpy(Tmap, pre.map, sizeof(Tmap));
    Node Tpre = pre;
    int xx = Tpre.x + dir[i][0];
    int yy = Tpre.y + dir[i][1];
    //判断是否入队
    if (check(xx, yy) && Tmap[xx][yy] != '#' && !(visit[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]]))
    {
    //如果下一个点为箱子的话
    if (Tmap[xx][yy] == '*')
    {
    int bx = xx + dir[i][0];
    int by = yy + dir[i][1];
    //判断箱子能否被推动
    if (check(bx, by) && Tmap[bx][by] != '#' && Tmap[bx][by] != '*')
    {
    int ii = 0;
    //查找推动的是哪个箱子
    for (ii = 0; ii < 3; ii ++)
    if (Tpre.Box[ii][1] == yy && Tpre.Box[ii][0] == xx)
    break;
    //推动后临时地图该点变为'*'
    Tmap[bx][by] = '*';
    //原来的两个点都变成'.'
    Tmap[pre.x][pre.y] = '.';
    Tmap[xx][yy] = '.';
    //如果前一个点是'@'(洞)的话
    if (T_map[pre.x][pre.y])
    Tmap[pre.x][pre.y] = '@';
    if (T_map[xx][yy])
    Tmap[xx][yy] = '@';
    Tpre.Box[ii][1] = by, Tpre.Box[ii][0] = bx;
    Tpre.x = xx, Tpre.y = yy;
    if ((visit[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]]))continue;
    }
    else continue;
    }
    nex.x = xx, nex.y = yy;
    for (int ii = 0; ii < 3; ii ++)
    {
    nex.Box[ii][0] = Tpre.Box[ii][0];
    nex.Box[ii][1] = Tpre.Box[ii][1];
    }
    //入队
    nex.step = Tpre.step + 1;
    visit[xx][yy][Tpre.Box[0][0]][Tpre.Box[0][1]][Tpre.Box[1][0]][Tpre.Box[1][1]][Tpre.Box[2][0]][Tpre.Box[2][1]] = true;
    memcpy(nex.map, Tmap, sizeof(nex.map));
    Que.push(nex);
    }
    }
    }
    }
    int main()
    {
    while (scanf("%d%d", &n, &m) != EOF)
    {
    memset(T_map, 0, sizeof(T_map));
    ans = -1;
    int numB = 0;
    for (int i = 0; i < n; i ++)
    {
    scanf("%s", map[i]);
    for (int j = 0; j < m; j ++)
    {
    if (map[i][j] == 'X') //记录起点
    {
    start.x = i, start. y = j;
    start.step = 0;
    map[i][j] = '.';
    }
    if (map[i][j] == '*') //记录箱子
    {
    start.Box[numB][0] = i, start.Box[numB ++][1] = j;
    }
    if (map[i][j] == '@') //记录洞
    {
    T_map[i][j] = 1;
    }
    }
    }
    memcpy(start.map, map, sizeof(start.map));
    BFS();
    printf("%d\n", ans);
    }
    return 0;
    }
  • 相关阅读:
    简单工厂设计模式
    MVC备忘
    在MVC后台代码中想实现删除时弹出"确认删除"效果
    集合
    嵌套
    整理 补课内容
    百鸡百钱
    ////输入一个100以内的数,判断是不是正整数;
    课后题 5 6
    课后题3,4
  • 原文地址:https://www.cnblogs.com/nanke/p/2364336.html
Copyright © 2011-2022 走看看