網易2017遊戲研發面試題 —— 推箱子(廣搜BFS判斷)
阿新 • • 發佈:2018-11-09
#include<iostream> #include <queue> #include <map> using namespace std; typedef pair<int, int> point; typedef pair<point, point>state; const int dirX[4] = { 0,0,1,-1 }; const int dirY[4] = { 1,-1,0,0 }; int N, M;//N行M列 //記錄人物箱子狀態 + 當前行走的步數 std::map<state, int>vis; queue<state> que; char mapping[10][10]; bool update(state s, int v) { //路徑中已經包含該狀態,即已經走過,沒必要走重蹈一遍 if (vis.find(s) != vis.end()) return false; //若該路徑還未走過,進行map新增 vis[s] = v; //加入佇列 que.push(s); return true; } bool checkPoint(point p) { //超過地圖範圍 if (p.first < 0 || p.second < 0 || p.first >= N || p.second >= M)return false; //該位置是否是障礙 if (mapping[p.first][p.second] == '#')return false; return true; } int bfs() { while(!que.empty()) { state s = que.front(); que.pop(); point people = s.first, box = s.second; //接下來,人物四個方向可以走 for(int i = 0; i < 4; ++i) { //人物新的位置 point newPeople = people; newPeople.first += dirX[i]; newPeople.second += dirY[i]; //判斷人物新的位置是否合理 if (!checkPoint(newPeople))continue; //判斷人物是否和當前箱子位置重合,如果重合,則進行推箱子 //箱子新的位置 point newBox = box; if(newPeople == box) { newBox.first += dirX[i]; newBox.second += dirY[i]; //判斷箱子往前推是否合理 if (!checkPoint(newBox))continue; //人物和箱子移動均合理的話,判斷箱子是否到達終點,進行return返回 if (mapping[newBox.first][newBox.second] == '@')return vis[s] + 1; } update(state(newPeople, newBox), vis[s] + 1); } } return -1; } int main() { cin >> N >> M; point peo, box;//初始人物與箱子的位置 for (int i = 0; i < N; ++i) for (int j = 0; j < M; ++j) { cin >> mapping[i][j]; if (mapping[i][j] == 'X') peo = point(i, j); if (mapping[i][j] == '*') box = point(i, j); } update(state(peo, box), 0); cout << bfs() << endl; return 0; }