HDU 1732——Push Box(BFS)

来源:互联网 发布:淘宝上代接信用卡电话 编辑:程序博客网 时间:2024/06/06 03:07

3个箱子一个人,要想记录状态必须用8维的hash。

思路:

先判断下一步的位置是否合法

1、如果下一个点是   ' . '     ,判重,如果合法,则直接走到下个位置,记录状态,入队

2、如果下一个点是箱子,先判断是第几个箱子,然后判断同方向上的再下一个位置是不是箱子或者是墙,如果是墙或者箱子,说明当前箱子推不了,否则,就把当前序号的箱子推到那个位置上,改变它的坐标,判重,如果合法,则入队


弱菜的代码都是膜拜大牛的,只是加了个备注,自己按思路敲了一遍,ORZ

#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define inf 0x3f3f3f3fusing namespace std;bool hash[8][8][8][8][8][8][8][8];char map[8][8];int n,m,ans;int dir[4][2]={{0,1,},{0,-1},{1,0},{-1,0}};struct node{    int x,y;};struct state{    node h,box[3];    int st;    bool isok()    {        if(h.x>=0&&h.x<n&&h.y>=0&&h.y<m&&map[h.x][h.y]!='#') return true;        return false;    }}a,b;void sethash(state cur)//记录状态{    hash[cur.h.x][cur.h.y][cur.box[0].x][cur.box[0].y][cur.box[1].x][cur.box[1].y][cur.box[2].x][cur.box[2].y]=true;}bool gethash(state cur)//判断当前状态是否走过{    return hash[cur.h.x][cur.h.y][cur.box[0].x][cur.box[0].y][cur.box[1].x][cur.box[1].y][cur.box[2].x][cur.box[2].y];}bool find(state cur)// 判断箱子是不是都推到洞里去了{    int i;    for(i=0;i<3;++i){        if(map[cur.box[i].x][cur.box[i].y]!='@') break;    }    if(i!=3) return false;    return true;}int isbox(state cur)//判断这个位置是不是箱子,如果是,返回箱子的序号{    for(int i=0;i<3;++i){        if(cur.h.x==cur.box[i].x&&cur.h.y==cur.box[i].y) return i;    }    return -1;}bool logic(state cur,int d,int cnt)//判断同方向上的下一个点,如果位置越界,或者是墙或箱子,返回false;{    state next;    next.h.x=cur.h.x+dir[d][0];    next.h.y=cur.h.y+dir[d][1];    if(!next.isok()) return false;    for(int i=0;i<3;++i){        if(next.h.x==cur.box[i].x&&next.h.y==cur.box[i].y&&i!=cnt) return false;    }    return true;//可以推箱子}int bfs(){    queue<state> q;    a.st=0;    q.push(a);    while(!q.empty()){        a=q.front(),q.pop();        if(find(a)){            return ans=a.st;        }        for(int i=0;i<4;++i){            b=a;            b.h.x=a.h.x+dir[i][0];            b.h.y=a.h.y+dir[i][1];            b.st=a.st+1;            if(!b.isok()) continue; //位置不合法            int which=isbox(b);             if(which!=-1){//如果 这个位置是箱子                if(logic(b,i,which)){ //同方向上的下个位置是路,把箱子推过去,改变它的坐标                    b.box[which].x=b.h.x+dir[i][0];                    b.box[which].y=b.h.y+dir[i][1];                    if(!gethash(b)){//当前状态没有记录过                        sethash(b);//记录状态                        q.push(b);//入队                    }                }            }            else{//当前位置是路或者是洞,直接走                if(!gethash(b)){                    sethash(b);                    q.push(b);                }            }        }    }    return -1;}int main(){    //freopen("input.txt","r",stdin);    //freopen("output.txt","w",stdout);    while(scanf("%d%d",&n,&m)!=EOF){        getchar();        int cnt=0;        for(int i=0;i<n;++i){            for(int j=0;j<m;++j){                map[i][j]=getchar();                if(map[i][j]=='X'){                    a.h.x=i,a.h.y=j;                }                if(map[i][j]=='*'){                    a.box[cnt].x=i,a.box[cnt++].y=j;//记录每个箱子的坐标                }            }            getchar();        }        memset(hash,false,sizeof hash);        sethash(a);        printf("%d\n",bfs());    }    return 0;}


0 0
原创粉丝点击