HDU 1254 推箱子 (bfs嵌套)

来源:互联网 发布:sql语句中的引号 编辑:程序博客网 时间:2024/06/05 10:35

思路:

    注意以下3点:

   (1)要考虑人是否能走到推箱子的地方

   (2)箱子经过的格子可以再次经过,而箱子经过同一个格子从同一个方向来的只能有一次,也就是不能再次从同

                     一方向推回原来的地方(因此要用到方向数组)

   (3)人不能穿过箱子

     AC代码如下:

     

#include<stdio.h>struct{     int men_x;   int men_y; /*men_x,men_y标记每次推动箱子后人的位置*/   int box_x;   int box_y;/*boy_x,boy_y标记每次推动箱子后箱子的位置*/   int x;   int y;/*x,y用于bfs_men()里人走动的坐标*/   int step;   int pre;/*标记箱子走动后的前驱*/}sq_box[100],sq_men[100];/*人的队列,以及箱子的队列*/int map[8][8];int fx[4]={1,-1,0,0},fy[4]={0,0,1,-1};int m,n;int rear1,front1,rear2,front2;int temp_box_x,temp_box_y,temp_men_x,temp_men_y;/*用于初始化人和箱子的坐标*/int men_x,men_y;/*箱子后面的坐标(要推动箱子必须要走到箱子的后面)*/int check(int x,int y){    int flag=0;if(0<=x&&x<m&&0<=y&&y<n)flag=1;return flag;}int bfs_men(){    int i;int x,y;int mask[8][8]={0};rear2=front2=0;sq_men[rear2].x=sq_box[front1].men_x;sq_men[rear2].y=sq_box[front1].men_y;/*开始时人的坐标入队*/mask[sq_box[front1].men_x][sq_box[front1].men_y]=1;rear2++;while(front2!=rear2){if(sq_men[front2].x==men_x&&sq_men[front2].y==men_y)return 1;    for(i=0;i<4;i++){   x=sq_men[front2].x+fx[i];   y=sq_men[front2].y+fy[i];   if(check(x,y)&&map[x][y]!=1&&mask[x][y]==0&&(x!=sq_box[front1].box_x||y!=sq_box[front1].box_y))/*最后一个条件是人不能穿过箱子到箱子的后面*/   {      sq_men[rear2].x=x;  sq_men[rear2].y=y;  mask[x][y]=1;  rear2++;   }}    front2++;}return 0;}int bfs_box(){    int i;int mask[7][7][4]={0};/*三维,最后一维代表方向*/int x,y,step;rear1=front1=0;sq_box[rear1].box_x=temp_box_x;sq_box[rear1].box_y=temp_box_y;sq_box[rear1].men_x=temp_men_x;sq_box[rear1].men_y=temp_men_y;sq_box[rear1].step=0;sq_box[rear1].pre=-1;rear1++;while(front1!=rear1){if(map[sq_box[front1].box_x][sq_box[front1].box_y]==3)return sq_box[front1].step;     for(i=0;i<4;i++) { x=sq_box[front1].box_x+fx[i]; y=sq_box[front1].box_y+fy[i]; step=sq_box[front1].step+1; if(check(x,y)&&map[x][y]!=1&&mask[x][y][i]==0) {    men_x=sq_box[front1].box_x-fx[i];men_y=sq_box[front1].box_y-fy[i];if(check(men_x,men_y)&&map[men_x][men_y]!=1){   if(bfs_men()){  sq_box[rear1].box_x=x;  sq_box[rear1].box_y=y;  sq_box[rear1].men_x=sq_box[front1].box_x;  sq_box[rear1].men_y=sq_box[front1].box_y;  sq_box[rear1].step=step;  sq_box[rear1].pre=front1;  mask[x][y][i]=1;  rear1++;}} } } front1++;}    return -1;}int main(){int i,j;int T;scanf("%d",&T);while(T--){scanf("%d%d",&m,&n);    for(i=0;i<m;i++)for(j=0;j<n;j++){   scanf("%d",&map[i][j]);   if(map[i][j]==2)   {      temp_box_x=i;  temp_box_y=j;   }   else if(map[i][j]==4)               {      temp_men_x=i;  temp_men_y=j;   }}printf("%d\n",bfs_box());}    return 0;}


 

    

     

原创粉丝点击