其中迷宮必須輸入爲如下形式的矩形:
0 0 0 0 0 0 0 0 0 0 0 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 x x x x x x x x x x x 0
0 0 0 0 0 0 0 0 0 0 0 0
其中x,要麼爲0,要麼爲1; 其中外圍的0表示牆壁(亦即邊界)
而原點與終點的輸入則爲上述矩陣的下標號(0,0)開始,如第一行第一列的點爲起點則輸入爲1 1,終點同理。
求解思路主要運用的是回溯法,即,當下一步不可通時,回到上一步繼續探測,直至找到終點或者所有路徑都探測完爲止。
代碼如下:
#include <iostream>
using namespace std;
#define MAX_SIZE 100
struct MazeNode{
bool passable; //0表示不能通過,1表示可以通過
int passed; //0表示爲經過該點,1表示該點可以通過,-1表示該點不可通
int xPosition; //x座標
int yPosition; //y座標
};
struct Stack{
MazeNode* elem;
int top;
};
void InitStack(Stack& stack){
stack.elem = new MazeNode[MAX_SIZE*10];
stack.top = 0;
}
bool IsEmpty(const Stack& stack){
if(stack.top == 0)
return true;
else return false;
}
void Push(Stack& stack, MazeNode elem){
stack.elem[stack.top] = elem;
stack.top++;
}
MazeNode Pop(Stack& stack){
if(!IsEmpty(stack)){
stack.top--;
MazeNode elem = stack.elem[stack.top];
return elem;
}else{
cout<<"棧已空!"<<endl;
}
}
bool FindPath(MazeNode* maze[], MazeNode start, MazeNode end){
Stack stack;
InitStack(stack);
if(start.passable == 0){
cout<<"入口不可通!"<<endl;
return false;
}
start.passed = 1;
MazeNode current = start;
Push(stack,current);
do{
if(current.passable == end.passable && current.xPosition == end.xPosition && current.yPosition == end.yPosition){
return true;
}
int x = current.xPosition;
int y = current.yPosition;
if(maze[x][y+1].passed == 0 && maze[x][y+1].passable == 1){//如果右鄰點沒走過且可通
cout<<"向右走到"<<"("<<x<<","<<y+1<<")->";
maze[x][y+1].passed = 1;
current = maze[x][y+1];
Push(stack,current);
}else if(maze[x+1][y].passed == 0 && maze[x+1][y].passable == 1){//如果下鄰點沒走過且可通
cout<<"向下走到"<<"("<<x+1<<","<<y<<")->";
maze[x+1][y].passed = 1;
current = maze[x+1][y];
Push(stack,current);
}else if(maze[x][y-1].passed == 0 && maze[x][y-1].passable == 1){//如果左鄰點沒走過且可通
cout<<"向左走到"<<"("<<x<<","<<y-1<<")->";
maze[x][y-1].passed = 1;
current = maze[x][y-1];
Push(stack,current);
}else if(maze[x-1][y].passed == 0 && maze[x-1][y].passable == 1){//如果上鄰點沒走過且可通
cout<<"向上走到"<<"("<<x-1<<","<<y<<")->";
maze[x-1][y].passed = 1;
current = maze[x-1][y];
Push(stack,current);
}else if(!IsEmpty(stack)){//如果棧不空,則回朔
current = Pop(stack);
cout<<"回退到"<<"("<<current.xPosition<<","<<current.yPosition<<")->";
}else{//如果棧爲空,則無解
return false;
}
}while(true);
}
void main(){
MazeNode** maze = NULL;
Stack stack;
InitStack(stack);
int i, j, row, col;
cout<<"迷宮大小(行、列數):";
cin>>row>>col;
if(row < 1 || col < 1){
cout<<"輸入非法!"<<endl;
cout<<"程序結束!"<<endl;
return ;
}
maze = new MazeNode*[row];
if(!maze){
cout<<"分配內存失敗!程序結束!"<<endl;
return ;
}
for(i = 0; i < row; i++){
maze[i] = new MazeNode[col];
if(!maze[i]){
cout<<"分配內存失敗!程序結束!"<<endl;
return ;
}
}
cout<<"請輸入迷宮:"<<endl;
for(i = 0; i < row; i++){
for(j = 0; j < col; j++){
cin>>maze[i][j].passable;
maze[i][j].xPosition = i;
maze[i][j].yPosition = j;
maze[i][j].passed = 0;
Push(stack,maze[i][j]);
}
}
cout<<"請輸入起始點與終止點:"<<endl;
MazeNode start, end;
cin>>start.xPosition>>start.yPosition>>end.xPosition>>end.yPosition;
start = maze[start.xPosition][start.yPosition];
end = maze[end.xPosition][end.yPosition];
if(FindPath(maze,start,end)){
cout<<endl<<"走出迷宮!"<<endl;
}else {
cout<<endl<<"迷宮不可通!"<<endl;
}
cout<<endl;
}