程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu1254推箱子(BFS)

hdu1254推箱子(BFS)

編輯:C++入門知識

題目鏈接:hdu1254

/*
用廣搜尋找最小步數,推箱子需要滿足以下幾個條件:
1.人能走到推箱子的那個位置
2.人不能穿過箱子.
3.箱子可以回到前一狀態的位置,但不是同一方向回到的
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
int d[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
int map[8][8];
int v[8][8][5];//第三維表示箱子在(i,j)時,是由哪個方向推過來的
int flag;
int n,m,ex,ey,sx,sy,rx,ry;
struct node
{
    int x, y;
    int step;
    int rx, ry;//表示箱子在(x,y)時,箱子之前的位置,也就是人推完箱子後,站在箱子原來的位置
    friend bool operator < (node a,node b)
    {
        return a.step > b.step;
    }
};
bool judge(int x, int y)
{
    if(x < 0 || x >= n || y < 0 || y >= m) return true;
    return false;
}
int p_bfs(int sx, int sy, int ex, int ey, int jx, int jy)
{

    bool f[8][8];
    memset(f, false, sizeof(f));
    priority_queue  q;
    node s, tmp;
    s.x = sx;
    s.y = sy;
    f[sx][sy] = true;
    s.step = 0;
    q.push(s);
    while(!q.empty())
    {
        tmp = q.top();
        q.pop();
        if(tmp.x == ex && tmp.y == ey)
            return 1;
        for(int i = 0; i < 4; i ++)
        {
            s.x = tmp.x + d[i][0];
            s.y = tmp.y + d[i][1];
            if(f[s.x][s.y]) continue;
            if(judge(s.x, s.y) || map[s.x][s.y] == 1 || (s.x == jx && s.y == jy)) continue;//不能穿過箱子
            s.step = tmp.step + 1;
            f[s.x][s.y] = true;
            q.push(s);
        }
    }
    return 0;
}
void bfs()
{
    memset(v, -1, sizeof(v));
    priority_queue  q;
    node s, tmp;
    s.x = sx;
    s.y = sy;
    s.rx = rx;
    s.ry = ry;
    s.step = 0;
    q.push(s);
    while(!q.empty())
    {
        tmp = q.top();
        q.pop();
        if(tmp.x == ex && tmp.y == ey)
        {
            flag = true;
            printf("%d\n",tmp.step);
            return ;
        }
        for(int i = 0; i < 4; i ++)
        {
            s.x = tmp.x + d[i][0];
            s.y = tmp.y + d[i][1];
            if(v[s.x][s.y][i] == i) continue;
            if(judge(s.x, s.y) || map[s.x][s.y] == 1) continue;

            int dx = tmp.x - d[i][0];//dx,dy表示人要推箱子時站的位置
            int dy = tmp.y - d[i][1];

            if(judge(dx, dy) || map[dx][dy] == 1) continue;//判斷位置是否越界,或該位置是牆

            if(p_bfs(tmp.rx, tmp.ry, dx, dy, tmp.x, tmp.y))
            {
                s.rx = tmp.x;
                s.ry = tmp.y;
                s.step = tmp.step + 1;
                v[s.x][s.y][i] = i;
                q.push(s);
            }
        }
    }
}
int main()
{
    int T,i,j;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(i = 0; i < n; i ++)
        for(j = 0; j < m; j ++)
        {
            scanf("%d",&map[i][j]);
            if(map[i][j] == 2) sx = i, sy = j;
            else if(map[i][j] == 3) ex = i, ey = j;
            else if(map[i][j] == 4) rx = i, ry = j;
        }
        flag = 0;
        bfs();
        if(!flag) puts("-1");
    }
    return 0;
}


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved