走迷宫
来源:互联网 发布:windows7查看mac地址 编辑:程序博客网 时间:2024/05/01 07:14
走迷宫
2013年9月,在一次实验课上碰到了这个问题。迷宫是一个二维数组,用递归回溯走,小迷宫可以这样走,大迷宫这样走就不行了。能力有限,没用最短路径去做。
结果截图:
代码如下:
//深度优先遍历(DFS)算法走迷宫。堆栈操作由操作系统完成,程序中不出现push()和pop()。//囧为要寻找的目的地,□为可行路径,■为不可行障碍(墙壁)。//找出迷宫中所有目的地囧和出口(即位于迷宫边缘的□)。#include <iostream>#include <conio.h>using namespace std;#define ROW 27 //迷宫行数,若修改下面矩阵则这里也要随之修改。#define RANK 39 //命令行窗口一行最多显示80个单字节字符,或20个双字节字符,故设置的迷宫列数最大只能到39。#define Dir_num 4 //4个方向,也是枚举类型Dir的模。#define ■ '0' //wall#define □ '1' //way#define 囧 'D' //destination#define ㊣ 'a' //reached destination//#define ⊙ 'T' //testing point#define ¤ 'e' //tested point#define ↑ 'u' //direction mark#define → 'r'#define ↓ 'd'#define ← 'l'#define └ '2' //turning point mark#define ┌ '3'#define ┐ '4'#define ┘ '5'char Puzzle[ROW][RANK] = {■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■, □,□,□,□,□,□,□,□,□,■,□,□,□,□,□,□,□,□,□,■,□,□,□,□,□,□,□,□,囧,■,□,□,□,□,□,□,□,□,□, ■,■,■,■,□,□,■,□,□,■,■,■,□,■,□,□,■,□,□,■,■,■,□,■,□,□,■,□,□,■,■,■,□,■,□,□,■,□,■, □,□,□,■,□,□,□,■,□,■,■,□,□,■,□,□,□,■,□,■,■,□,□,■,□,□,□,■,□,■,■,□,□,■,□,□,□,■,■, ■,■,□,□,■,■,■,■,□,□,□,□,■,□,□,□,□,■,□,■,■,■,■,□,□,□,□,■,□,■,■,■,■,□,□,□,□,■,■, ■,□,□,□,□,□,□,■,□,■,□,□,□,□,□,□,□,□,■,■,■,□,□,□,□,□,□,□,■,■,■,□,□,□,□,□,□,□,■, ■,□,□,■,□,□,□,■,□,■,□,□,□,■,□,□,□,□,□,■,■,□,□,■,□,□,□,□,□,■,■,□,□,■,□,□,□,□,■, ■,□,■,■,■,■,■,■,□,■,□,□,■,■,■,■,■,■,□,■,■,□,■,■,■,■,■,■,□,■,■,□,■,■,■,■,■,■,■, ■,□,■,■,■,■,■,■,□,■,□,□,■,■,■,■,■,■,■,■,■,□,■,■,■,■,■,■,■,■,■,□,■,■,■,■,■,■,■, ■,□,□,□,□,□,□,■,□,■,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,■,■,□,■,■,■,■,■,■,■, ■,■,□,■,□,□,■,□,□,■,■,■,□,■,□,□,■,□,□,■,■,■,□,■,□,□,■,□,□,■,□,□,□,□,□,□,□,□,■, ■,□,□,■,□,□,□,■,□,□,■,□,□,■,□,□,□,■,□,■,■,□,□,■,□,□,□,■,□,■,■,■,□,■,□,□,■,□,■, ■,■,■,□,□,□,□,■,□,□,■,■,■,□,□,□,□,■,□,■,■,■,■,□,□,□,□,■,□,■,■,□,□,■,□,□,□,■,■, ■,□,□,□,□,□,□,□,■,□,■,□,□,□,□,□,□,□,■,■,■,□,□,□,□,□,□,□,■,■,■,■,■,□,□,□,□,■,■, ■,□,□,■,□,□,□,□,■,□,□,□,□,■,□,□,□,□,□,■,■,□,□,□,□,□,□,□,□,■,■,□,□,□,□,□,□,□,■, ■,□,■,■,■,■,■,■,■,■,■,□,■,■,■,■,■,■,□,■,■,□,■,□,■,■,■,■,□,■,■,□,□,■,□,□,□,□,■, ■,□,■,■,■,■,■,■,□,□,□,■,■,■,■,■,■,■,■,■,■,□,■,■,■,■,□,■,■,■,■,□,■,■,■,■,■,■,■, ■,□,□,□,□,□,□,□,□,■,□,□,□,□,□,□,□,□,□,■,□,□,□,□,□,□,□,□,□,■,■,□,□,□,□,□,□,□,■, ■,■,□,■,□,□,■,□,□,□,■,■,□,■,□,□,■,□,□,■,□,■,□,■,□,□,■,□,□,□,■,□,■,■,■,■,■,■,■, ■,□,□,■,□,□,□,■,□,□,■,□,□,■,■,□,□,■,□,■,■,□,□,■,□,□,□,■,□,■,□,□,□,□,□,□,□,□,■, ■,■,■,□,□,□,□,■,□,□,■,■,■,□,囧,■,□,■,□,■,□,■,■,□,□,□,□,■,□,■,■,■,□,■,□,□,■,□,■, ■,□,□,□,□,□,□,□,■,□,■,□,□,□,□,■,□,□,■,■,□,□,□,□,□,□,□,□,■,■,□,□,□,■,□,□,□,■,■, ■,□,□,■,□,□,□,□,□,□,■,□,□,■,□,□,□,□,□,■,□,□,□,■,□,□,□,□,□,■,■,■,■,□,□,□,□,■,■, ■,□,□,■,□,□,□,■,□,■,■,□,■,■,■,■,■,■,□,■,□,□,■,□,□,■,■,■,■,□,□,□,□,□,□,□,□,□,■, ■,□,■,■,■,■,■,■,■,■,■,□,□,□,□,□,□,□,■,■,□,□,■,■,■,■,□,□,■,□,■,□,□,■,□,□,□,□,□, ■,□,■,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,□,■,□,■,■,■,■,■,■,■, ■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■,■, }; //迷宫矩阵。int pos_row = 1; //记录起点行位置。int pos_rank = 0; //记录起点列位置。enum Dir {U, R, D, L}; //用来索引方向数组的枚举值,只用来作为定位vec[4]数组的偏移值。Dir to; //设这个变量只是为了减少重复计算,以及使vec[]的下标短一点。class Cod //Coordinate{public:int x;int y;Cod(int a=0, int b=0):x(a), y(b) {};}; const Cod vec[Dir_num] = {Cod(-1, 0), Cod(0, 1), Cod(1, 0), Cod(0, -1)}; //方向数组,可以用下标来控制移动方向。void display() //直观地输出当前路径。{int i, j;cout << '\n';for(i = 0; i < ROW; i++){ for(j = 0; j < RANK; j++) switch(Puzzle[i][j]) { //case ⊙:{ cout << "⊙"; break;}; case ■:{ cout << "■"; break;}; case □:{ cout << " "; break;}; case 囧:{ cout << "囧"; break;}; case ㊣:{ cout << "囧"; break;}; case ¤:{ cout << " "; break;}; case ↑:{ cout << "↑"; break;}; case →:{ cout << "→"; break;}; case ↓:{ cout << "↓"; break;}; case ←:{ cout << "←"; break;}; case └:{ cout << "└"; break;}; case ┌:{ cout << "┌"; break;}; case ┐:{ cout << "┐"; break;}; case ┘:{ cout << "┘"; break;}; default :{}; }; //switch cout << '\n';}; //for(i)cout << endl;};void seek(const int& x,const int& y,const Dir& from) //递归函数。{//下面两个if为递归结束条件。if( ! ((x >= 0) && (x < ROW) && (y >= 0) && (y < RANK)))return; //下标越界,返回上级函数。if((Puzzle[x][y] != 囧) && (Puzzle[x][y] != □))return; //只要遇到不是目的地囧或可行位置□,便返回上级函数。//下面这个if为找到目的地(囧)或遇到出口(位于迷宫边缘的□)时的提示。if(Puzzle[x][y] == 囧){ Puzzle[x][y] = ㊣; //这里标记一下纯粹是因为接下来要display(),不然就不能画出当前找到的目的地囧。 cout << '\n' <<"----------------------------------------------------------------------------" << '\n'; cout << '(' << x << ',' << y << ')' <<"is a destination." << endl; display(); cout << "按任意键继续走..."; _getch();}else if((Puzzle[x][y] == □) && ((x == 0) || (x == ROW-1) || (y == 0) || (y == RANK-1)) && ((x != pos_row) || (y != pos_rank))){ switch(from) //同上,为画出当前出口。{ case U:{ Puzzle[x][y] = ↓; break; }; case R:{ Puzzle[x][y] = ←; break; }; case D:{ Puzzle[x][y] = ↑; break; }; case L:{ Puzzle[x][y] = →; break; }; default:{}; }; //switch cout << '\n' <<"----------------------------------------------------------------------------" << '\n'; cout << "An exit found:" << '(' << x << ',' << y << ")." <<endl; display(); cout << "按任意键继续走..."; _getch();};//搜索当前位置上的除from方向的三个方向的格子,并按方向标记当前位置。to = Dir((from + 2) % Dir_num);if(Puzzle[x][y] != ㊣)switch(from){ case U:{ Puzzle[x][y] = ↓; break; }; case R:{ Puzzle[x][y] = ←; break; }; case D:{ Puzzle[x][y] = ↑; break; }; case L:{ Puzzle[x][y] = →; break; }; default:{};}; //switchseek(x + vec[to].x, y + vec[to].y, Dir((to + 2) % Dir_num)); //搜寻from方向的【对侧】方向的格子。to = Dir((from + 1) % Dir_num);if(Puzzle[x][y] != ㊣)switch(from){ case U:{ Puzzle[x][y] = └; break; }; case R:{ Puzzle[x][y] = ┌; break; }; case D:{ Puzzle[x][y] = ┐; break; }; case L:{ Puzzle[x][y] = ┘; break; }; default:{};}; //switchseek(x + vec[to].x, y + vec[to].y, Dir((to + 2) % Dir_num)); //搜寻from方向的【后续】方向的格子。第三个参数是避免递归函数回头又搜寻来时的方向,下同。to = Dir((from + 3) % Dir_num);if(Puzzle[x][y] != ㊣)switch(from){ case U:{ Puzzle[x][y] = ┘; break; }; case R:{ Puzzle[x][y] = └; break; }; case D:{ Puzzle[x][y] = ┌; break; }; case L:{ Puzzle[x][y] = ┐; break; }; default:{};}; //switchseek(x + vec[to].x, y + vec[to].y, Dir((to + 2) % Dir_num)); //搜寻from方向的【前驱】方向的格子。if(Puzzle[x][y] != ㊣) //对已遍历完三个方向的位置,标记为已遍历完(¤),以免重复检查该位置。Puzzle[x][y] = ¤;};void main(){display();seek(pos_row, pos_rank, R);if(Puzzle[pos_row][pos_rank] == ㊣) //如果上一个seek()因为方向不对而不能继续遍历迷宫,则肯定会改变入口位置的状态,为了使接下来按反方向遍历的seek()顺利遍历,需把入口位置变回原来状态。Puzzle[pos_row][pos_rank] = 囧;else if(Puzzle[pos_row][pos_rank] == ¤)Puzzle[pos_row][pos_rank] = □;seek(pos_row, pos_rank, L); //为了防止上面的seek()因为方向不对而不能继续遍历,这里按反方向遍历。cout << '\n' << "终于走完了~~" << '\n' << endl;} //main()
0 0
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- 走迷宫
- Windows store app测量字符串所占UI空间的大小
- 搜索引擎 -python实现
- ARM寄存器中a1、ip的含义 ARM寄存器的别名
- csu1510: Happy Robot
- 理解radiance irradiance
- 走迷宫
- angularJS 基础回顾
- C#调用托管C++类(DLL)
- 游戏开发常用算法 (一)
- 关于android_webview,html5_appcache
- [转]百度搜索研发部:日志分析方法概述
- C# FileStream、StreamWriter、StreamReader读写文件时BOM头问题
- JAVA设计模式(十四)——适配器模式
- Caffe + Ubuntu 14.04 64bit + CUDA 6.5 配置说明