赞
踩
迷宫问题(栈与队列)
[问题描述]
利用栈操作实现迷宫问题求解。
[基本要求]
(1)从文件中读取数据,生成模拟迷宫地图,不少于20行20列。
(2)给出任意入口和出口,显示输出迷宫路线。
文件内容:
这道题和八皇后问题比较类似。八皇后问题是在满足一定条件下,在一张图中寻找皇后放置的合适位置。这里则是根据出口和入口,在一张迷宫图中寻找路线,路线上的各点需满足:不重复且不为墙壁。
我们首先从文件中读取数据,生成迷宫地图。之后找出所有的迷宫口,并选定入口和出口。从入口出发,每次都对上下左右的四个位置进行探测,若该点满足条件(不重复且不为墙壁),则加入保存路线的栈route中(这里我们用visit[][]数组标注某一位置是否可行)。若未到达指定出口,且某一位置无法继续前进时,则将栈顶位置弹栈,处理前一位置,若仍无法继续前进,继续弹栈,直到可以前进为止。
按照此方法找到的路线即为从入口到出口的路线,路线上的各点保存在栈route中,最后打印输出包含路线的迷宫图即可。
- # include <iostream>
- # include <fstream>
- # include <string.h>
- # include <stack>
- # define maxn 30
- using namespace std;
-
- //地图类型的结构体
- typedef struct Point {
- int col; //行
- int row; //列
- }Point;
-
- //创建迷宫
- void Create();
- //打印迷宫
- void Print();
- //生成出入口
- void FindGate();
- //判断位置是否可行
- bool Judge(int x, int y);
- //走迷宫
- void GoMaze();
-
- int m = 0, n = 0; //迷宫的行、列
- int maze[maxn][maxn]; //迷宫地图
- int gate[maxn][2]; //保存迷宫出入口
- int vis[maxn][maxn]; //记录走过的位置
- //在迷宫的前进方式
- int way[4][2] = { {0,1},{-1,0},{1,0},{0,-1} };
- stack<Point>route; //保存路线的栈
- int path[maxn][maxn] = { {0} }; //路线
-
- int main()
- {
- Create(); //创建迷宫
- Print(); //打印迷宫图
- int select;
- while (1) {
- cout << "\n开始游戏!" << endl;
- FindGate(); //生成出入口
- GoMaze(); //走迷宫
- cout << endl;
- Print(); //打印迷宫图(包含路线)
- for (int i = 1; i <= m; i++) {
- for (int j = 1; j <= n; j++) {
- path[i][j] = 0;
- vis[i][j] = 0;
- }
- }
- cout << "\n是否继续游戏? (1:是 2:否)" << endl;
- cout << "请输入:";
- cin >> select;
- if (select != 1) {
- break;
- }
- }
- cout << "\n游戏结束!" << endl;
- return 0;
- }
-
- //创建迷宫
- void Create()
- {
- fstream file;
- file.open("迷宫样例.txt", ios::in);
- if (file.fail()) {
- cout << "文件打开失败" << endl;
- exit(0);
- }
- char str[100];
- char c;
- int i = 0;
- file.getline(str, 100);
- while (str[i] != ' ' && i < strlen(str)) {
- m *= 10;
- m = m + str[i] - 48;
- i++;
- }
- i++;
- while (str[i] != ' ' && i < strlen(str)) {
- n *= 10;
- n = n + str[i] - 48;
- i++;
- }
- int k = 1, j;
- file.getline(str, 100);
- while (!file.eof()) {
- j = 1;
- for (int i = 0; i < strlen(str); i = i + 2)
- {
- maze[k][j] = str[i] - 48;
- j++;
- }
- k++;
- file.getline(str, 100);
- }
- j = 1;
- for (int i = 0; i < strlen(str); i = i + 2) {
- maze[k][j] = str[i] - 48;
- j++;
- }
- }
-
- //打印迷宫及路线
- void Print()
- {
- for (int i = 1; i <= m; i++) {
- for (int j = 1; j <= n; j++) {
- if (maze[i][j]) {
- cout << "D";
- }
- else if (path[i][j]) {
- cout << "*";
- }
- else {
- cout << " ";
- }
- }
- cout << endl;
- }
- }
-
- //生成出入口
- void FindGate()
- {
- int k = 1; //出入口序号
- for (int i = 1; i <= m; i++) {
- if (maze[i][1] == 0) {
- cout << "(" << k << ")";
- cout << i << " " << 1 << endl;
- gate[k][0] = i;
- gate[k][1] = 1;
- k++;
- }
- if (maze[i][n] == 0) {
- cout << "(" << k << ")";
- cout << i << " " << n << endl;
- gate[k][0] = i;
- gate[k][1] = n;
- k++;
- }
- }
- for (int i = 2; i < n; i++) {
- if (maze[1][i] == 0) {
- cout << "(" << k << ")";
- cout << 1 << " " << i << endl;
- gate[k][0] = 1;
- gate[k][1] = i;
- k++;
- }
- if (maze[m][i] == 0) {
- cout << "(" << k << ")";
- cout << m << " " << i << endl;
- gate[k][0] = m;
- gate[k][1] = i;
- k++;
- }
- }
- }
-
- //判断位置是否可行
- bool Judge(int x, int y)
- {
- if (x > m || x < 1 || y > n || y < 1 || maze[x][y] || vis[x][y]) {
- //超过边界或该点为墙壁或上一次走过,则不通
- return false;
- }
- else {
- return true;
- }
- }
-
- //走迷宫
- void GoMaze()
- {
- int x, y, x1, y1, x2, y2;
- cout << "请输入入口序号:";
- cin >> x;
- x1 = gate[x][0];
- y1 = gate[x][1];
- cout << "请输入出口序号:";
- cin >> y;
- x2 = gate[y][0];
- y2 = gate[y][1];
- Point current; //现在所处的位置
- current.col = x1;
- current.row = y1;
- path[current.col][current.row] = 1;
- vis[current.col][current.row] = 1;
- route.push(current); //将入口放入路线
- //到达终点前会一直寻找路线
- while (current.col != x2 || current.row != y2) {
- int t = 0; //判断是否可以继续前进
- while (!t) {
- for (int i = 0; i < 4; i++) {
- current.col = current.col + way[i][0];
- current.row = current.row + way[i][1];
- if (Judge(current.col, current.row)) {
- //可以继续前进
- t = 1;
- route.push(current); //将该位置放入路线
- path[current.col][current.row] = 1;
- vis[current.col][current.row] = 1;
- break;
- }
- else {
- //不通
- current.col = current.col - way[i][0];
- current.row = current.row - way[i][1];
- continue;
- }
- }
- if (!t) {
- //若不能继续前进,则弹栈
- if (!route.empty()) {
- route.pop();
- }
- path[current.col][current.row] = 0;
- //更新当前位置
- if (!route.empty()) {
- current.col = route.top().col;
- current.row = route.top().row;
- }
- }
- }
- }
- }
运行结果:
- DDD DDDDDD DDDD
- DDDDDD DD D DDDD
- DD DDD DD DDDDDD DDDD
- DD DDD DDD D DDDDDD DDDD
- DD DDDDDDD D
- DD DDDD D DDDDDDDDDD
- DDDD DDD DDD DDDDDDDDDD
- DDDD D DDD DDDDDDDDDD
- DDDD DDD D D DDDDD
- DDDD DDD D D DDDDDD DDDDD
- DDDD D D DDD DDDDD
- DDDDDDDDDD DDDD DDD DDDDD
- DDD D DDDD DDD DDDDD
- DDD DDDD D DDD
- DDD DDDDDDDDD DDDDD DDDDD
- DDD DDDD DDDDD DDDDD
- DDD DDDD DDDD DDDDD DDDDD
- DDD DDDD DDDD DDDDD DDDDD
- DDD DDDD DDDDD
- DDD DDDD DD DDD DDDDDDDDD
- DDD DDD DDDDDDDDD
- DDD DDDDDD DDDD DD
- DDD DDDDDD DDDDDD DDDD DD
- DDD DDDDDD DDDDDD DDDD DD
- DDDDDD DDDD DDDD
-
- 开始游戏!
- (1)1 1
- (2)5 25
- (3)14 25
- (4)25 1
- (5)25 25
- (6)1 2
- (7)25 2
- (8)1 3
- (9)25 3
- (10)1 4
- (11)25 4
- (12)1 5
- (13)1 6
- (14)1 7
- (15)1 11
- (16)25 11
- (17)1 12
- (18)1 13
- (19)1 14
- (20)25 16
- (21)25 17
- (22)25 18
- (23)1 21
- (24)25 23
- (25)25 24
- 请输入入口序号:1
- 请输入出口序号:5
-
- *******DDD DDDDDD DDDD
- DDDDDD* DD D DDDD
- DD*****DDD DD DDDDDD DDDD
- DD*DDD DDD D DDDDDD DDDD
- DD*DDDDDDD D
- DD*** DDDD D DDDDDDDDDD
- DDDD*DDD***DDD DDDDDDDDDD
- DDDD*****D*DDD DDDDDDDDDD
- DDDD DDD D*D DDDDD
- DDDD DDD D*D DDDDDD DDDDD
- DDDD D*D DDD DDDDD
- DDDDDDDDDD*DDDD DDD DDDDD
- DDD******D*DDDD DDD DDDDD
- DDD*DDDD*** D DDD
- DDD*DDDDDDDDD DDDDD DDDDD
- DDD******DDDD DDDDD DDDDD
- DDD DDDD*DDDD DDDDD DDDDD
- DDD DDDD*DDDD DDDDD DDDDD
- DDD DDDD******** DDDDD
- DDD DDDD DD DDD*DDDDDDDDD
- DDD DDD*DDDDDDDDD
- DDD DDDDDD DDDD********DD
- DDD DDDDDD DDDDDD DDDD*DD
- DDD DDDDDD DDDDDD DDDD*DD
- DDDDDD DDDD DDDD***
-
- 是否继续游戏? (1:是 2:否)
- 请输入:1
-
- 开始游戏!
- (1)1 1
- (2)5 25
- (3)14 25
- (4)25 1
- (5)25 25
- (6)1 2
- (7)25 2
- (8)1 3
- (9)25 3
- (10)1 4
- (11)25 4
- (12)1 5
- (13)1 6
- (14)1 7
- (15)1 11
- (16)25 11
- (17)1 12
- (18)1 13
- (19)1 14
- (20)25 16
- (21)25 17
- (22)25 18
- (23)1 21
- (24)25 23
- (25)25 24
- 请输入入口序号:2
- 请输入出口序号:4
-
- DDD DDDDDD DDDD
- DDDDDD DD D DDDD
- DD DDD DD DDDDDD DDDD
- DD DDD DDD D DDDDDD DDDD
- DD DDDDDDD D***********
- DD DDDD D*DDDDDDDDDD
- DDDD DDD DDD*DDDDDDDDDD
- DDDD D DDD*DDDDDDDDDD
- DDDD DDD D D ******DDDDD
- DDDD DDD D D DDDDDD*DDDDD
- DDDD D D DDD*DDDDD
- DDDDDDDDDD DDDD DDD*DDDDD
- DDD D DDDD DDD*DDDDD
- DDD DDDD D DDD*
- DDD DDDDDDDDD DDDDD*DDDDD
- DDD******DDDD DDDDD*DDDDD
- DDD*DDDD*DDDD DDDDD*DDDDD
- DDD*DDDD*DDDD DDDDD*DDDDD
- DDD*DDDD* *********DDDDD
- DDD*DDDD*DD*DDD DDDDDDDDD
- DDD* ****DDD DDDDDDDDD
- DDD*DDDDDD DDDD DD
- DDD*DDDDDD DDDDDD DDDD DD
- DDD*DDDDDD DDDDDD DDDD DD
- ****DDDDDD DDDD DDDD
-
- 是否继续游戏? (1:是 2:否)
- 请输入:2
-
- 游戏结束!
以上便是我对这道题的看法,很高兴与大家分享。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。