标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6416 Accepted Submission(s):
1834
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 struct node 7 { 8 int x,y; //箱子的位置 9 int xx,xy; //人的位置 10 int t; //箱子动的格数 11 } s1,s2; 12 int f[4][2]= {0,1,0,-1,1,0,-1,0}; //方向变量 13 int map[10][10]; //记录地图 14 int vis[10][10][10][10]; //四维数组标记,同时记录箱子的位置和人的位置,去除重复的 15 int n,m; //边界 16 int a1,a2,b1,b2; //初始值 17 int flag[10][10],kk; 18 19 bool xx(int a,int b) 20 { 21 if(a>=0&&a<n&&b>=0&&b<m&&map[a][b]!=1) return true; 22 return false; 23 } 24 25 void DFS(int nx,int ny,int mx,int my) 26 { 27 if(nx==mx&&ny==my) //如果从要到的点能搜到此时人的位置,则人可以走过来 28 { 29 kk=1; //若能走来,标记为1 30 return; 31 } 32 for(int i=0; i<4&&!kk; i++) 33 { 34 int x=nx+f[i][0]; 35 int y=ny+f[i][1]; 36 if(xx(x,y)&&!flag[x][y]) 37 { 38 flag[x][y]=1; //走过的点标记为1 39 DFS(x,y,mx,my); //继续搜索 40 } 41 } 42 } 43 44 void BFS() 45 { 46 queue<node> q; 47 while(!q.empty()) 48 q.pop(); 49 int nx,ny; 50 s1.x=a1; //初始化 51 s1.y=b1; 52 s1.xx=a2; 53 s1.xy=b2; 54 s1.t=0; 55 vis[a1][b1][a2][b2]=1; //开始状态标记为已出现 56 q.push(s1); 57 while(!q.empty()) 58 { 59 s1=q.front(); 60 q.pop(); 61 if(map[s1.x][s1.y]==3) //箱子到达指定位置后,队列循环结束 62 { 63 printf("%d\n",s1.t); 64 return; 65 } 66 for(int i=0; i<4; i++) 67 { 68 s2.x=s1.x+f[i][0]; //箱子移动后的位置 69 s2.y=s1.y+f[i][1]; 70 nx=s1.x-f[i][0]; //如果箱子能移动到那个位置,人必须能走到这个点 71 ny=s1.y-f[i][1]; 72 if(xx(s2.x,s2.y)&&xx(nx,ny)&&!vis[s2.x][s2.y][nx][ny]) 73 //xx()函数判断是否超边界和是否是墙,箱子移动后的位置和人要到的位置都必须满足,并且此时这个状态是没有出现过的 74 { 75 memset(flag,0,sizeof(flag)); //地图中所有不是墙的点都能走 76 flag[nx][ny]=flag[s1.x][s1.y]=1; //箱子移动前的位置和人要到的位置都看做墙 77 kk=0; //标记人是否能走过来 78 DFS(nx,ny,s1.xx,s1.xy); //深搜查询 79 if(kk) //如果人能走到 80 { 81 vis[s2.x][s2.y][nx][ny]=1; //这个状态标记已出现 82 s2.xx=nx; //记录此时人到的位置 83 s2.xy=ny; 84 s2.t=s1.t+1; //步数加一 85 q.push(s2); //入队列 86 } 87 } 88 } 89 } 90 printf("-1\n"); //如果不能到,则输出-1 91 return; 92 } 93 int main() 94 { 95 int T,i,j; 96 scanf("%d",&T); 97 while(T--) 98 { 99 scanf("%d%d",&n,&m); 100 memset(vis,0,sizeof(vis)); //标记全部初始化为0 101 for(i=0; i<n; i++) 102 for(j=0; j<m; j++) 103 { 104 scanf("%d",&map[i][j]); 105 if(map[i][j]==2) //记录箱子的起始位置 106 { 107 a1=i; 108 b1=j; 109 } 110 if(map[i][j]==4) //记录人的起始位置 111 { 112 a2=i; 113 b2=j; 114 } 115 } 116 BFS(); 117 } 118 return 0; 119 }
标签:
原文地址:http://www.cnblogs.com/pshw/p/4934349.html