HDU 1254 推箱子(搜索)

来源:互联网 发布:java api 1.7 苹果版 编辑:程序博客网 时间:2024/05/19 20:37

转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove


以前就做过的一题,重温一下

推箱子游戏,首先广搜箱子的路径,每一次移动都要判断人是否能到达指定位置(BFS,DFS都行),我采用两次BFS解决问题

在箱子的移动中,判重的时候需要一个三维数组,箱子从不同方向过来,人的位置是不一样的,也就意味着状态不一样

/*ID:cxlove*/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<vector>#define LL unsigned long longusing namespace std;int n,m,T;int way[4][2]={{0,1},{0,-1},{1,0},{-1,0}};int str[10][10];struct Node{int x,y,step;int mmap[10][10];bool check(){if(x>=0&&x<n&&y>=0&&y<m)return true;return false;}}s,e,u,v,ss,ee,uu,vv;bool bfs_people(Node n1){   //搜索人是否能到达指定位置queue<Node>que;ss=n1;bool flag[10][10];memset(flag,false,sizeof(flag));for(int i=0;i<n;i++){   //找到人的起点for(int j=0;j<m;j++)if(n1.mmap[i][j]==4){ss.x=i;ss.y=j;ss.step=0;}}if(ss.x==ee.x&&ss.y==ee.y)return true;que.push(ss);flag[ss.x][ss.y]=true;while(!que.empty()){uu=que.front();que.pop();for(int i=0;i<4;i++){vv=uu;vv.step++;vv.x+=way[i][0];vv.y+=way[i][1];if(vv.check()&&flag[vv.x][vv.y]==false&&(n1.mmap[vv.x][vv.y]!=1&&n1.mmap[vv.x][vv.y]!=2)){ //目标点不是墙也不是箱子flag[vv.x][vv.y]=true;if(vv.x==ee.x&&vv.y==ee.y)return true;que.push(vv);}}}return false;}int bfs_box(){ //搜索箱子int flag[10][10][4];queue<Node>que;que.push(s);memset(flag,false,sizeof(flag));while(!que.empty()){u=que.front();que.pop();for(int i=0;i<4;i++){v=u;v.x+=way[i][0];v.y+=way[i][1];v.step++;if(v.check()&&str[v.x][v.y]!=1&&flag[v.x][v.y][i]==false){//人的目标位置ee.x=u.x-way[i][0];ee.y=u.y-way[i][1];if(ee.check()==false)continue;if(bfs_people(v)){//更新地图,箱子和人的位置swap(v.mmap[v.x][v.y],v.mmap[u.x][u.y]);swap(v.mmap[ee.x][ee.y],v.mmap[ss.x][ss.y]);flag[v.x][v.y][i]=true;if(str[v.x][v.y]==3)return v.step;que.push(v);}}}}return -1;}int main(){int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=0;i<n;i++)for(int j=0;j<m;j++){scanf("%d",&str[i][j]);s.mmap[i][j]=str[i][j];if(str[i][j]==2){   //标注箱子起点s.x=i;s.y=j;s.step=0;}}printf("%d\n",bfs_box());}return 0;}


原创粉丝点击