中文题目:http://acm.hdu.edu.cn/showproblem.php?pid=1254 一开始常规的人用来做主导,想着想着不对劲,其实是箱子为主导,人只是箱子能否推进的一个判断。 可以使用两个BFS,人这里也可以DFS。看见别人有用四维标记的有用图中图的判重,我也用一下图中图好了。 #include<iostream> #include<queue> using namespace std; int n, m; int map[10][10]; int vec[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}}; int visited[10][10][4];//标记箱子。有四个方向,所有一个点可以推四次 int visitedP[10][10];//标记人 struct node { int x; int y; int step; int innerMap[10][10];//保存每个点修改的图 bool check() { if(x>=0 && x<n && y>=0 && y<m) return true; return false; } }boxStart, peopleStart, peopleEnd, target; int PeopleBFS(node t) { peopleStart = t; memset(visitedP, 0, sizeof(visitedP)); queue<node> Q; //找人的位置 for (int i = 0; i<n; i++) { for (int j = 0; j<m; j++) { if (t.innerMap[i][j] == 4) { peopleStart.x = i; peopleStart.y = j; peopleStart.step = 0; } } } if(peopleStart.x == peopleEnd.x && peopleStart.y == peopleEnd.y) return true; visitedP[peopleStart.x][peopleStart.y] = true; Q.push(peopleStart); while (!Q.empty()) { node q = Q.front(); Q.pop(); for (int i = 0; i<4; i++) { node p = q; p.x += vec[i][0]; p.y += vec[i][1]; p.step++; if (p.check() && !visitedP[p.x][p.y] && t.innerMap[p.x][p.y]!=1 && t.innerMap[p.x][p.y]!= 2)//不是墙不是箱 { visitedP[p.x][p.y] = true; if (p.x == peopleEnd.x && p.y == peopleEnd.y)//可以到 { return true; } Q.push(p); } } } return false; } int BoxBFS() { queue<node> Q; Q.push(boxStart); while (!Q.empty()) { node q = Q.front(); Q.pop(); for (int i = 0; i<4; i++) { node p = q; p.x += vec[i][0]; p.y += vec[i][1]; p.step++; if (p.check() && !visited[p.x][p.y][i] && map[p.x][p.y] != 1) { //找出人站在箱子前进方向的反方向 peopleEnd = q; peopleEnd.x = q.x - vec[i][0]; peopleEnd.y = q.y - vec[i][1]; if (peopleEnd.check())//人可以站在这个位置 { if (PeopleBFS(peopleEnd))//人可以到达 { swap(p.innerMap[p.x][p.y], p.innerMap[q.x][q.y]);//箱子走一步 swap(p.innerMap[peopleEnd.x][peopleEnd.y], p.innerMap[peopleStart.x][peopleStart.y]);//人跟上 visited[p.x][p.y][i] = true; if (map[p.x][p.y] == 3)//到达目的地 { return p.step; } Q.push(p); } } } } } return -1; } int main() { int T; cin>>T; while (T--) { cin>>n>>m; memset(visited, 0, sizeof(visited)); for (int i = 0; i<n; i++) { for (int j = 0; j<m; j++) { cin>>map[i][j]; boxStart.innerMap[i][j] = map[i][j]; if (map[i][j] == 2)//箱子起始 { boxStart.x = i; boxStart.y = j; boxStart.step = 0; } } } cout<<BoxBFS()<<endl; } return 0; }