回溯--迷宫问题

感觉做了两个回溯之后都差不多....

#include <iostream>
#include <stack>
using namespace std;


typedef enum{AVAILABEL, ROUTE, BACKTRACKED, WALL} Status; //前期准备 记录当前迷宫的状态,分别为可用(未探索),已用,已经探测过没有退路的,还有墙
typedef enum{ UNKNOWN, EAST, SOUTH, WEST, NORTH, NO_WAY} ESWN;
//enum方向,从unknown开始,到NORTH,遇到NO_WAY就要回溯并标记 BACKTRACKED

inline ESWN nextESWN ( ESWN eswn)
{
return ESWN(eswn + 1);
}

//这个内联函数用来返回方向的
 
struct Cell{
int x, y;
Status status;
ESWN incoming, outgoing;
};
//迷宫宫格

#define LABY_MAX 24
Cell labe[LABY_MAX][LABY_MAX];


inline Cell* neighbor (Cell* cell)
{
switch (cell->outgoing){
case EAST : return cell + LABY_MAX;
case SOUTH : return cell + 1;
case WEST : return cell - LABY_MAX;
case NORTH : return cell - 1;
default:  exit(-1);
}
}
//去探测当前cell的下一个邻居cell

inline Cell* advance (Cell* cell){
Cell *next;
switch (cell ->outgoing){
case EAST : 
next =  cell + LABY_MAX;
next ->incoming = WEST;
break;
case SOUTH : 
next =  cell + 1;
next ->incoming = NORTH;
break;
case WEST : 
next = cell - LABY_MAX;
next ->incoming = EAST;
break;
case NORTH : next = cell - 1;
next ->incoming = SOUTH;
break;
default:  exit(-1);
}
return next;
}
//跳转到下一个邻居,并给邻居做上标记
bool laberinth(Cell Laby[LABY_MAX][LABY_MAX], Cell *sourth, Cell *tail)
{
if ((AVAILABEL != sourth->status) || (AVAILABEL != tail ->status))
{
return false;
}
//这是用来处理初始条件不符合的情况

stack <Cell*> path;
sourth->incoming = UNKNOWN;
sourth -> status = ROUTE;
path.push(sourth);
//初始设定,我觉得也应该将outgoing 设置成UNKNOWN的

do  //不断循环,直到遍历所有,或者有结果
{
Cell *c = path.top(); //当前位置,若和出口相等,退出
if (c == tail)
{
return true;
}
while(NO_WAY > (c -> outgoing = nextESWN(c->outgoing))) //不断去探索路,直到找到没去过的

//如果没有,就回溯
if (AVAILABEL == neighbor(c)->status) break;
if (NO_WAY <= c->outgoing)
{
c->status = BACKTRACKED;
path.pop();
}
else //可以的话就push c的邻居进去,并且标记
{
path.push(c = advance(c));
c->outgoing = UNKNOWN;
c->status = ROUTE;
}
} while (!path.empty());


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值