1254 推箱子

来源:互联网 发布:淘宝蜂蜜属于什么类目 编辑:程序博客网 时间:2024/04/29 07:12

(c语言版)整体思路:主线是以箱子为中心做广搜,能不能扩展某个点的条件是人能不能到到达(箱子要去方向的反方向这点)这时再写一个广搜(搜人能否到达这点),(人的位置总是在箱子移动前的位置可以找到不熟的话做hdu 1026打印路径的题)(要扩展的目标终点也有,可以写)整理代码的严谨性和逻辑性就完成了。

#include<cstdio>#include<cstring>using namespace std;const int N=10;int next[4][2]={{0,1},{1,0},{0,-1},{-1,0}};int book[N][N][N][N];struct f{ int x,y,step; int early;}b[4*N*N],c[4*N*N];int a[N][N];int bookx[N][N];int n,m,peox,peoy,bx,by;int jud(int px,int py){//people+box   int head=0,tail=1;   c[head].x=peox,c[head].y=peoy;   if(peox==px&&peoy==py) return 1;//如果人的初始位置满足条件就不需要扩展点了(开始忘了这个细节)   memset(bookx,0,sizeof(bookx));   while(head<tail){       for(int i=0;i<4;i++)       {           int tx=c[head].x+next[i][0],ty=c[head].y+next[i][1];           if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]==1||bookx[tx][ty]) continue;           if(tx==bx&&ty==by) continue;              bookx[tx][ty]=1;            c[tail].x=tx,c[tail++].y=ty;           if(tx==px&&ty==py) {return 1;}       }       head++;   }   return 0;}int main(){    int t;    scanf("%d",&t);    while(t--){        int startx,starty,endx,endy;        scanf("%d%d",&n,&m);//输错行列        for(int i=1;i<=n;i++)         for(int j=1;j<=m;j++)            {             scanf("%d",&a[i][j]);             if(a[i][j]==2){startx=i,starty=j;}             if(a[i][j]==3){endx=i,endy=j;}             if(a[i][j]==4){peox=i,peoy=j;}            }      int head=0,tail=1,flag=0;      b[head].x=startx,b[head].y=starty,b[head].step=0,b[head].early=0;      memset(book,0,sizeof(book));      while(head<tail){          bx=b[head].x,by=b[head].y;//箱子位置        if(head){peox=b[b[head].early].x,peoy=b[b[head].early].y;}//人的位置(为箱子上个的位置)          for(int i=0;i<4;i++)          {              int tx=bx+next[i][0],ty=by+next[i][1];              int px=bx-next[i][0],py=by-next[i][1];              if(tx<1||tx>n||ty<1||ty>m||a[tx][ty]==1) continue;              if(px<1||px>n||py<1||py>m) continue;              if(!book[bx][by][tx][ty]&&jud(px,py)){//四维标记(人的位置(即当前箱子的位置)加箱子的位置)                  book[bx][by][tx][ty]=1;                  b[tail].x=tx,b[tail].y=ty,b[tail].step=b[head].step+1,b[tail++].early=head;                  if(tx==endx&&ty==endy){                        flag=1;break;                  }              }          }          if(flag) break;          head++;      }      if(flag) printf("%d\n",b[tail-1].step);      else printf("-1\n");    }return 0;}


0 0