hdoj 1732(推箱子)(利用hash来判断状态,而不是map)

来源:互联网 发布:医生移动工作站软件 编辑:程序博客网 时间:2024/04/29 18:26
#include <iostream>#include <queue>#include <stdio.h>using namespace std;char map[10][10];//地图int n,m,lmin;int x[5] = {1,-1,0,0};//方向int y[5] = {0,0,1,-1};//方向bool hash[8][8][8][8][8][8][8][8];//这个是人的状态class Point{public:int x,y;};class State{public:Point hum,box[3];int step;public:bool isok(){        if(hum.x >= 0 && hum.x < n && hum.y >= 0 && hum.y < m && map[hum.x][hum.y] != '#')            return true;        return false;}};State now,next;queue<State>q;void setHash(State node){    hash[node.hum.x][node.hum.y][node.box[0].x][node.box[0].y][node.box[1].x][node.box[1].y][node.box[2].x][node.box[2].y] = true;}bool getHash(State node){    return hash[node.hum.x][node.hum.y][node.box[0].x][node.box[0].y][node.box[1].x][node.box[1].y][node.box[2].x][node.box[2].y];}//判断这个地方是哪个箱子int isBox(State next){for(int i=0;i<3;i++){if(next.hum.x==next.box[i].x && next.hum.y==next.box[i].y){return i;}}return -1;}//人(第which个箱子)能否移动(which是箱子的id箱子的移动方向跟人的移动方向相同)bool canMove(State next,int dir,int which){//移动人next.hum.x+=x[dir];next.hum.y+=y[dir];//是否越界(如果说一移动,越界啦,那么返回false)if(!next.isok())return false;//如果说一移动,下面是箱子,那么返回false(如果说是第which个箱子,跳过)int i;for(i=0;i<3;i++){if(i!=which && (next.hum.x == next.box[i].x && next.hum.y == next.box[i].y)){return false;}}return true;}//是否结束(三个箱子都在@的地方)bool finish(State next){if(map[next.box[0].x][next.box[0].y] == '@' && map[next.box[1].x][next.box[1].y] == '@' && map[next.box[2].x][next.box[2].y] == '@')return true;return false;}void bfs(){int i;//如果队列不为空while(!q.empty()){//出栈一个now=q.front();q.pop();//是否结束if(finish(now)){if(lmin>now.step){lmin=now.step;}break;//也就是说继续运算,但是不再向下}//四个方向for(i=0;i<4;i++){//向下走一步next=now;next.hum.x+=x[i];next.hum.y+=y[i];next.step++;//步子++//这个是否越界if(next.isok()){int which=isBox(next);//如果说下一步是箱子(首先要判断是否移动箱子,那么再向下走一步,判断能否走)if(which != -1){if(canMove(next,i,which)){//移动一步箱子next.box[which].x+=x[i];next.box[which].y+=y[i];//是否访问过(如果访问过,跳过,如果没有访问过,压入队列)if(!getHash(next)){//标记访问过(压入队列)setHash(next);q.push(next);}}}//如果说下一个不是箱子else{//如果说这个点没有访问过if(!getHash(next)){//设置访问过setHash(next);//压入队列q.push(next);}}}}}}int main(){int i,j;while(scanf("%d %d",&n,&m)!=EOF){//输入for(i=0;i<n;i++)scanf("%s",map[i]);//初始化int cnt=0;for(i = 0; i < n; i++)for(j = 0;j < m; j++){if(map[i][j]=='X')now.hum.x=i,now.hum.y=j;if(map[i][j]=='*')now.box[cnt].x=i,now.box[cnt++].y=j;}//把第一个点的脚步做成0now.step=0;        memset(hash,false,sizeof(hash));//吧第一个点表示为访问过setHash(now);//初始化lmin=100000;//清空队列while(!q.empty())q.pop();//把第一个点压入队列当中q.push(now);//处理bfs();//输出if(lmin==100000){cout<<"-1"<<endl;}else{cout<<lmin<<endl;}}}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 剖腹产奶涨的疼怎么办 生产一天了没奶怎么办 第一天断奶 奶水一直流出怎么办 新生儿刚出生没奶水怎么办 安卓手机死机了怎么办 婴幼儿几天不拉大便怎么办 樱桃吃多了胃不舒服怎么办 空腹吃水果胃不舒服怎么办 吃水果后胃不舒服怎么办 吃水果伤胃了怎么办 大人吃退烧药不出汗怎么办 稍微吃点凉水果胃就疼怎么办 1岁宝宝感冒发烧怎么办 3岁小儿反复发烧怎么办 热感冒喉咙疼要怎么办 孩子感冒咳嗽嗓子疼怎么办 孕妇感冒了嗓子疼咳嗽怎么办 4岁宝宝反复高烧怎么办 小孩吃完药不退烧怎么办 六个月婴儿发烧怎么办退烧快点 咳嗽20天老不好怎么办 吃过退烧药出汗怎么办 5岁儿童发烧39度怎么办 小孩烧到39度怎么办 儿童7岁发烧39度怎么办 发烧没药怎么办怎样退烧快 小孩发烧怎么办怎样退烧快 发烧头疼怎么办最快最有效 发烧头晕怎么办最快最有效 婴儿发烧怎么办最快最有效 孩子一直37度8怎么办 一岁半宝宝37度5怎么办 发烧打了针35度怎么办 小孩发烧吃了鱼怎么办 八个月婴儿发烧39度怎么办 婴儿反复发烧39度怎么办 宝宝发烧了怎么办如何退烧 宝宝烧到38.8度怎么办 小孩发烧到39度怎么办 宝贝发烧到40度怎么办 孩子发烧39度8怎么办