特点: 1:此题不要标记,因为走过的点可能还要走,进入方向不一样(如果点的特征会发生变化,那么就不能标记) 2:由于此题不能拉,所以在箱子移动的时候,必须要判断是否有某点,从该点人可以把箱子移到目标位置(DFS) #include <iostream> #include <cstdio> #include <queue> #include <string.h> using namespace std; int n,m,sx,sy,ex,ey,ptx,pty,s[15][15],vis[15][15][15][15],flag[15][15]; struct node { int x,y,px,py; int step; }; int dir[4][2]={1,0,-1,0,0,1,0,-1}; //dfs功能为:判断点(x,y)能不能移到点(ssx,ssy) int dfs(int x,int y,int ssx,int ssy) { if (x==ssx&&y==ssy) return 1; for (int i=0;i<4;++i) { int x1=x+dir[i][0]; int y1=y+dir[i][1]; if (x1<=0||x1>n||y1<=0||y1>m||s[x1][y1]==1||flag[x1][y1]) continue; flag[x1][y1]=1; if (dfs(x1,y1,ssx,ssy)) return 1; } return 0; } void BFS() { queue<node>Q; node cur,next; cur.x=sx; cur.y=sy; cur.px=ptx; cur.py=pty; cur.step=0; vis[cur.x][cur.y][cur.px][cur.py]=1; Q.push(cur); while(!Q.empty()) { cur=Q.front(); Q.pop(); if (cur.x==ex&&cur.y==ey) { printf ("%d\n",cur.step); return; } int i,ssx,ssy; for (i=0;i<4;++i) { next.x=cur.x+dir[i][0];//下一点箱子的位置 next.y=cur.y+dir[i][1]; next.px=cur.x;//下一点人站的位置 next.py=cur.y; next.step=cur.step+1; if (next.x<=0||next.x>n||next.y<=0||next.y>m||vis[next.x][next.y][next.px][next.py]||s[next.x][next.y]==1) continue; ssx=cur.x-dir[i][0];//人移动箱子要站的位置 ssy=cur.y-dir[i][1]; if (ssx<=0||ssx>n||ssy<=0||ssy>m||s[ssx][ssy]==1) continue; s[cur.x][cur.y]=1;//由于dfs时,该点被箱子占据,所以不能行走 memset(flag,0,sizeof(flag)); flag[cur.px][cur.py]=1;//起点 if (dfs(cur.px,cur.py,ssx,ssy)) { vis[next.x][next.y][next.px][next.py]=1; Q.push(next); } s[cur.x][cur.y]=0; } } printf ("-1\n"); } int main() { int t,i,j; scanf("%d",&t); while(t--) { memset(vis,0,sizeof(vis)); scanf("%d%d",&n,&m); for (i=1;i<=n;++i) { for (j=1;j<=m;++j) { scanf("%d",&s[i][j]); if (s[i][j]==2) sx=i,sy=j; if (s[i][j]==3) ex=i,ey=j; if (s[i][j]==4) ptx=i,pty=j; } } BFS(); } return 0; }