迷宮求解問題的簡易實現(C++)

其中迷宮必須輸入爲如下形式的矩形:

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;
}

發佈了28 篇原創文章 · 獲贊 6 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章