中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

求迷宮通路問題

發布時間:2020-05-04 18:49:57 來源:網絡 閱讀:643 作者:腳印C 欄目:編程語言

    本次我們探討一下迷宮小游戲。

讓我們來探討一下怎樣可以得到一條通路,采用棧來實現。

    當是通路的時候,節點壓棧。當走到盡頭不通時,出棧,尋找交叉口,尋找通路。

求迷宮通路問題

像這樣在第一行存放迷宮的規格(在這里為傳參少,定義正方形迷宮),設計迷宮,將迷宮以.txt格式存放在目錄下(可以是任何地方,下文以默認路徑為例)。

    假設入口為(2,0),出口為迷宮最后一行任意位置。


    MAZE.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
#include<assert.h>
#include<stack>

class Pos  //迷宮每一點的坐標
{
public:
 Pos(int row,int col)
  :_row(row)
  , _col(col)
 {}

 int _row;
 int _col;
};


void PrintPos(Pos& pos)// 打印節點坐標
{
 cout << "(" << pos._row << ", " << pos._col << ") ";
}


int* GetMaze(int& N)//從文件中打開迷宮
{
 FILE *font = fopen("maze.txt", "r");
 assert(font != NULL);//打不開迷宮文件無意義

 char ch;
 while ((ch = fgetc(font)) != '\n')
 {
  N = N * 10 + ch - '0';
 }

 int *a = new int[N*N];
 for (int i = 0; i < N*N, (ch = fgetc(font)) != EOF;)
 {
  if (ch == '1' || ch == '0')
  {
   a[i] = ch - '0';
   i++;
  }
 }
 return a;
}

void PrintMaze(int *a, const int N)//打印迷宮
{
 cout << "\n迷宮地圖  ('0'為路, '1'為墻)" << endl;

 for (int i = 0; i < N; i++)
 {
  for (int j = 0; j < N; j++)
  {
   cout << a[i * 10 + j] << " ";
  }
  cout << endl;
 }
}

bool IsOverScope(Pos pos, const int N)//判斷是否越界
{
 if (pos._col < 0 || pos._col >= N || pos._row < 0 || pos._row >= N)
 {
  return true;
 }
 return false;
}

bool IsEndPoint(Pos pos, const int N)  //判斷是否為終點:設迷宮終點為能到達迷宮N-1行
{
 if (pos._col >= 0 && pos._col < N && pos._row == N - 1)
 {
  return true;
 }
 return false;
}


bool SearchMazePath(int* a, const int N, Pos enrty, stack<Pos>& paths) //尋找通路
{
 //若某一位置節點為0,進行壓棧,且將數據改為2,尋找此節點上下左右位置為0的節點,再進行壓棧,
 //若某一位置上下左右沒有為0的節點,就出棧尋找上一個節點上下左右為0的節點進行壓棧 
 assert(a);
 Pos top = paths.top();
 a[top._row*N + top._col] = 2;
 while (!IsOverScope(paths.top(), N))//每次都要判斷坐標是否越界、還要考慮出口旁邊也是出口的情況就會多走幾次
 {

  //判斷是否到達出口
  if (IsEndPoint(top, N))
  {
   return true;
  }

  if (0 == a[(top._row - 1)*N + top._col])//上
  {
   a[(top._row - 1)*N + top._col] = 2;
   Pos tmp(top._row - 1, top._col);
   paths.push(tmp);
   top = paths.top();
   continue;
  }
  if (0 == a[top._row * N + top._col + 1])//右
  {
   a[top._row * N + top._col + 1] = 2;
   Pos tmp(top._row, top._col + 1);
   paths.push(tmp);
   top = paths.top();
   continue;
  }

  if (0 == a[(top._row + 1)*N + top._col])//下
  {
   a[(top._row + 1)*N + top._col] = 2;
   Pos tmp(top._row + 1, top._col);
   paths.push(tmp);
   top = paths.top();
   continue;
  }
  if (0 == a[top._row * N + top._col - 1])//左
  {
   a[top._row * N + top._col - 1] = 2;
   Pos tmp(top._row, top._col - 1);
   paths.push(tmp);
   top = paths.top();
   continue;
  }
  //if (0 == a[top._row * N + top._col + 1] && top._col + 1 < N)//右
  //{
  // a[top._row * N + top._col + 1] = 2;
  // Pos tmp(top._row, top._col + 1);
  // paths.push(tmp);
  // top = paths.top();
  // continue;
  //}

  
  //回退
  if (a[top._row*N + top._col] == 2 && !paths.empty())
  {
   paths.pop();
   if (!paths.empty())
   {
    top = paths.top();   
    continue;
   }
   else
   {
    return false;
   }
  }
 }


 //if (IsOverScope(top, N) || paths.empty())//從上左右出來 
 return false;
 
}
 
 
void PrintPath(stack<Pos> paths)  //打印通路
{
 //最少Paths中有一個元素enrty在最底層
 assert(!paths.empty());
 cout << "通路: " << endl;;
 while (!paths.empty())
 {
  PrintPos(paths.top());
  paths.pop();
 }

 cout << endl;
}


    test.cpp

#include"MAZE.h"

void test()
{
 //假設迷宮為N*N型正方形

 int N = 0;
 int *a = GetMaze(N);
 PrintMaze(a, N);

 Pos enrty(2,0);

 stack<Pos> paths;
 paths.push(enrty);

 if (SearchMazePath((int*)a, N, enrty, paths))
 {
  PrintMaze(a, N);
  PrintPath(paths);
 }
 else
 {
  PrintMaze(a, N);
  cout << "There is not a path in this maze!" << endl;
 }

}


int main()
{
 test();

 system("pause");
 return 0;
}


讓我們來看看運行結果。


求迷宮通路問題


再試試將最后一行的‘0’改為1,讓它變成無通路的迷宮


求迷宮通路問題


我們可以在思考一下:

    當有好幾條通路的時候,我們可以得到最短路嗎?

求迷宮通路問題


我們可以得到以下思路:

    記錄最小路的步數 ,到達出口時將出口變為1 ,尋找下一條出口,然后更新最短路.

若要尋找這條最短路,那就可以在尋找一次,當通路的步數與最短路步數一致時輸出通路。


    但是上述方法存在很大的問題:雖然可以得到一個結果,但是不能夠保證就是最短的。

因為,當按照上述編程尋找通路的邏輯 “上右下左” 順序尋找通路時,就可能會把另一條更短的通路堵住,從而影響最短路的結果。


求迷宮通路問題


那到底怎么做呢? 期待下一篇博客。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绵竹市| 天峻县| 盐城市| 崇信县| 江川县| 阜南县| 油尖旺区| 荣成市| 镇坪县| 盐池县| 河津市| 涿鹿县| 共和县| 翁源县| 法库县| 泸水县| 大冶市| 天津市| 登封市| 长子县| 都江堰市| 奉贤区| 台北县| 曲松县| 积石山| 广饶县| 枣庄市| 封丘县| 武定县| 台南市| 峨边| 加查县| 邓州市| 乌兰浩特市| 禹城市| 韶山市| 砀山县| 资溪县| 慈利县| 正镶白旗| 大连市|