思路:
注意以下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; }