hdu1732

hdu1732 Push Box
传送门

题意

有一个\(n*m(2\leq n,m\leq 8)\)的网格,每个网格上有五种类型的元素之一:人,箱子,洞,空地,墙。人只有\(1\)个,共有\(3\)个箱子和\(3\)个洞,移动方向有上下左右四种,当人移动时碰到箱子,并且箱子的下一个位置是空地或者洞时,箱子可以跟着移动。计算将\(3\)个箱子全部推入洞中需要的最小步数,无法实现则输出\(-1\)

题解

\(bfs\)计算最小步数。
记录状态时,需要记录人和\(3\)个箱子的位置,共有\(8\)个坐标,开一个八维标记数组。
人移动之后,首先判断新的位置是否合法(不越界并且不是墙),如果新的位置是箱子,还要判断沿着当前移动方向的下一个位置是否合法并且没有被其他箱子占据。

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define LD long double
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PLI pair<LL,int>
#define pi acos(-1.0)
#define eps 1e-6
#define lowbit(x) x&(-x)
using namespace std;
 
int n,m,dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool book[8][8][8][8][8][8][8][8],hole[8][8];
char a[10][10];

struct node{
    int box[3][2];
    int x,y,step;
}t1,t2,st,ed;

queue<node> q;

bool finish(node t){
    for(int i=0;i<3;i++){
        if(!hole[t.box[i][0]][t.box[i][1]]) return false;
    }
    return true;
}

bool judge(int x,int y){
    if(x<0 || x>=n || y<0 || y>=m || a[x][y]=='#') return false;
    return true;
}

int bfs(){
    if(finish(st)) return st.step;
    memset(book,0,sizeof(book));
    memset(hole,0,sizeof(hole));
    for(int i=0;i<3;i++) hole[ed.box[i][0]][ed.box[i][1]]=1;
    while(!q.empty()) q.pop();
    t2=st;
    q.push(t2);
    book[t2.box[0][0]][t2.box[0][1]][t2.box[1][0]][t2.box[1][1]][t2.box[2][0]][t2.box[2][1]][t2.x][t2.y]=1;
    while(!q.empty()){
        t1=q.front();
        q.pop();
        for(int i=0;i<4;i++){
            int tx=t1.x+dir[i][0];
            int ty=t1.y+dir[i][1];
            if(!judge(tx,ty)) continue;
            int j;
            for(j=0;j<3;j++){
                if(tx==t1.box[j][0] && ty==t1.box[j][1]){
                    break;
                }
            }
            if(j<3){
                int tx2=tx+dir[i][0];
                int ty2=ty+dir[i][1];
                if(!judge(tx2,ty2)) continue;
                int k;
                for(k=0;k<3;k++){
                    if(tx2==t1.box[k][0] && ty2==t1.box[k][1]){
                        break;
                    }
                }
                if(k<3){
                    continue;
                }
                else{
                    t2=t1;
                    t2.box[j][0]=tx2;
                    t2.box[j][1]=ty2;
                    t2.x=tx;
                    t2.y=ty;
                    if(!book[t2.box[0][0]][t2.box[0][1]][t2.box[1][0]][t2.box[1][1]][t2.box[2][0]][t2.box[2][1]][t2.x][t2.y]){
                        t2.step++;
                        if(finish(t2)) return t2.step;
                        q.push(t2);
                        book[t2.box[0][0]][t2.box[0][1]][t2.box[1][0]][t2.box[1][1]][t2.box[2][0]][t2.box[2][1]][t2.x][t2.y]=1;
                    }
                }
            }
            else{
                t2=t1;
                t2.x=tx;
                t2.y=ty;
                if(!book[t2.box[0][0]][t2.box[0][1]][t2.box[1][0]][t2.box[1][1]][t2.box[2][0]][t2.box[2][1]][t2.x][t2.y]){
                    t2.step++;
                    if(finish(t2)) return t2.step;
                    q.push(t2);
                    book[t2.box[0][0]][t2.box[0][1]][t2.box[1][0]][t2.box[1][1]][t2.box[2][0]][t2.box[2][1]][t2.x][t2.y]=1;
                }
            }
        }
    }
    return -1;
}

int main(){
    while(scanf("%d %d",&n,&m)!=EOF){
        for(int i=0;i<n;i++) scanf("%s",a+i);
        int cnt1=0,cnt2=0;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(a[i][j]=='X'){
                    st.x=i;
                    st.y=j;
                }
                if(a[i][j]=='*'){
                    st.box[cnt1][0]=i;
                    st.box[cnt1++][1]=j;
                }
                if(a[i][j]=='@'){
                    ed.box[cnt2][0]=i;
                    ed.box[cnt2++][1]=j;
                }
            }
        }
        st.step=0;
        printf("%d\n",bfs());
    }
}
posted @ 2021-03-18 09:53  fxq1304  阅读(45)  评论(0编辑  收藏  举报