面试OR笔试43——走迷宫

来源:互联网 发布:域名注册排行榜 编辑:程序博客网 时间:2024/06/05 06:08

1 题目及要求

1.1 题目描述

如图所示为一个迷宫的分布图,其中灰色表示有障碍物不能通过。现在要从绿色的方格开始,每次只能走一格,制定方案如何能走到红色的终点方格处。给出一个可能的方案即可。

 

2 解答

2.1 题目分析

用回溯法。每次向一个方向走一格,看能否达到目的地,能则输出方案并返回;否则退回来向其他方向探索。

 

2.2 代码

#include <iostream>#include <vector>using namespace std;struct Point {int x, y;Point(int x1 = 0, int y1 = 0) :x(x1), y(y1) {}};bool findPath(vector<vector<bool>> &mat, Point target, vector<Point> &path) {int rows(mat.size()), cols(mat[0].size());Point start(path.back());if (start.x == target.x && start.y == target.y) return true;if (start.x < rows - 1 && mat[start.x + 1][start.y]) {// 下path.push_back({ start.x + 1,start.y });mat[start.x + 1][start.y] = false;if (findPath(mat, target, path)) return true;path.pop_back();}if (start.y < cols - 1 && mat[start.x][start.y + 1]) {// 右path.push_back({ start.x,start.y + 1 });mat[start.x][start.y + 1] = false;if (findPath(mat, target, path)) return true;path.pop_back();}if (0 < start.x && mat[start.x - 1][start.y]) {// 上path.push_back({ start.x - 1, start.y });mat[start.x - 1][start.y] = false;if (findPath(mat, target, path)) return true;path.pop_back();}if (0 < start.y && mat[start.x][start.y - 1]) {// 左path.push_back({ start.x,start.y - 1 });mat[start.x][start.y - 1] = false;if (findPath(mat, target, path)) return true;path.pop_back();}return false;}vector<Point> findPath(vector<vector<bool>> mat, Point start, Point target) {vector<Point> path;path.push_back(start);if (!findPath(mat, target, path)) path.pop_back();return path;}int main() {vector<vector<bool>> mat = {{0,0,0,0,0,0,0,0,0,0},{0,0,0,0,0,0,0,0,0,0},{0,0,1,1,0,1,1,1,0,1},{0,0,1,1,0,1,1,1,0,1},{0,0,1,1,1,1,0,0,1,1},{0,0,1,0,0,0,1,1,1,1},{0,0,1,1,1,0,1,1,1,1},{0,0,1,0,1,1,1,0,1,1},{0,0,1,0,0,0,1,0,0,1},{0,0,0,1,1,1,1,1,1,1},{0,0,0,0,0,0,0,0,0,1} };auto p(findPath(mat, { 1,2 }, { 10,9 }));for (size_t k1(0),kt(p.size());k1 < kt;++k1) {cout << "(" << p[k1].x << "," << p[k1].y << ")";if (k1 < kt - 1) cout << "->";}return 0;}

下面是在图中把适合的路径标示出来的代码。


#include <iostream>#include <vector>using namespace std;class Maze {public:Maze(const vector<vector<char>>& m) :mat(m) {}bool findPath(const vector<int>& xy);friend ostream& operator<<(ostream&, const Maze&);private:// 0空, 1障碍, 2不可行, 11到14分别表示4个方向static const char RI = 11, UP = 12, LE = 13, DO = 14;vector<vector<char>> mat;bool visit(int x1, int y1, int x2, int y2);};bool Maze::findPath(const vector<int>& xy) {if (mat.size() < 1 || xy.size() < 4) return false;for (auto &v : mat)for (auto &c : v) c = !!c;auto res = visit(xy[0], xy[1], xy[2], xy[3]);for (auto &v : mat)for (auto &c : v) c = c == 2 ? 0 : c;return res;}bool Maze::visit(int x1, int y1, int x2, int y2) {static int rows(mat.size()), cols(mat[0].size());if (x1 == x2 && y1 == y2) return true;if (x1 < rows - 1 && !mat[x1 + 1][y1]) {// 下mat[x1 + 1][y1] = DO;if (visit(x1 + 1, y1, x2, y2)) return true;mat[x1 + 1][y1] = 2;}if (y1 < cols && !mat[x1][y1 + 1]) {// 右mat[x1][y1 + 1] = RI;if (visit(x1, y1 + 1, x2, y2)) return true;mat[x1][y1 + 1] = 2;}if (0 < x1 && !mat[x1 - 1][y1]) {// 上mat[x1 - 1][y1] = UP;if (visit(x1 - 1, y1, x2, y2)) return true;mat[x1 - 1][y1] = 2;}if (0 < y1 && !mat[x1][y1 - 1]) {// 左mat[x1][y1 - 1] = LE;if (visit(x1, y1 - 1, x2, y2)) return true;mat[x1][y1 - 1] = 2;}return false;}ostream& operator<<(ostream& os, const Maze& ma) {for (auto &v : ma.mat) {for (auto &c : v) {switch (c){case Maze::RI:os << "→";break;case Maze::UP:os << "↑";break;case Maze::LE:os << "←";break;case Maze::DO:os << "↓";break;case 1:os << "█";break;default:os << " ";break;}}os << endl;}return os;}int main() {vector<vector<char>> mat = {{ 1,1,1,1,1,1,1,1,1,1 },{ 1,0,0,1,0,0,0,1,0,1 },{ 1,0,0,1,0,0,0,1,0,1 },{ 1,0,0,0,0,1,1,0,0,1 },{ 1,0,1,1,1,0,0,0,0,1 },{ 1,0,0,0,1,0,0,0,0,1 },{ 1,0,1,0,0,0,1,0,0,1 },{ 1,0,1,1,1,0,1,1,0,1 },{ 1,1,0,0,0,0,0,0,0,1 },{ 1,1,1,1,1,1,1,1,0,1 } };Maze m(mat);m.findPath({ 0,1,9,8 });cout << m;return 0;}


 

原创粉丝点击