代碼如下:
#include <iostream>
#include <queue>
using namespace std;
//const char * dirs = "NESW";
//const char * turns = "FLR";
const int N = 0, E = 1, S = 2, W = 3;
const int F = 0, L = 1, R = 2;
//分別表示N(上),E(右),S(下),W(左)
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
//移動的角色有三個屬性(行,列,方向)
typedef struct Node
{
Node(){}
Node(int row, int col, int d):r(row), c(col), dir(d){}
int r;
int c;
int dir;
}Node;
int END_POINT_ROW = 3;
int END_POINT_COL = 3;
/*
*p[0][0][]的情況是浪費的空間,因爲座標是從p[1][1][]開始;
*d[0][0][]的情況是浪費的空間,因爲座標是從d[1][1][]開始
*has_edge[0][0][]的情況是浪費的空間,因爲座標是從has_edge[1][1][][]開始
*/
Node p[4][4][4]; //保存的是父節點(行,列,方向);建立終點往回找的線索
int d[4][4][4]; //標記當前節點是否走過
bool has_edge[4][4][4][3] = {0}; //保存角色下一步能走的方向(FLR)
//判斷角色是否越界了
bool inside(int r, int c)
{
if(3 == r && 1 == c || 3 == r && 3 == c) return true;
if(r >= 1 && r <= 2 && c >= 1 && c <= 3) return true;
return false;
}
//通過前一點的移動方向,得到下一點的位置
Node walk(const Node &u, int turn)
{
int dir = u.dir;
if(turn == 1) dir = (dir + 3) % 4;
if(turn == 2) dir = (dir + 1) % 4;
return Node(u.r + dr[dir], u.c + dc[dir], dir);
}
//從終點開始回溯查找起點,並從起點開始打印走過的路
void print_ans(Node u)
{
vector<Node> nodes;
for(;;)
{
nodes.push_back(u);
if(d[u.r][u.c][u.dir] == 0) break;
u = p[u.r][u.c][u.dir];
}
//nodes.push_back(Node(r0, c0, dir));
Node nodeBegin(3, 1, N);
nodes.push_back(nodeBegin);
int cnt = 0;
for(int i = nodes.size() - 1; i >= 0; i--)
{
if(cnt % 10 == 0) printf(" ");
printf(" (%d,%d)", nodes[i].r, nodes[i].c);
if(++cnt % 10 == 0) printf("\n");
}
if(nodes.size() % 10 != 0) printf("\n");
}
void solve()
{
queue<Node> q;
memset(d, -1, sizeof(d));
//Node u(r1, c1, dir);
Node u(2, 1, N);
d[u.r][u.c][u.dir] = 0;
q.push(u);
while(!q.empty())
{
Node u = q.front(); q.pop();
if(u.r == END_POINT_ROW && u.c == END_POINT_COL) { print_ans(u); return;}
for(int i = 0; i < 3; i++)
{
Node v = walk(u, i);
if(has_edge[u.r][u.c][u.dir][i] && inside(v.r, v.c)
&& d[v.r][v.c][v.dir] < 0)
{
d[v.r][v.c][v.dir] = d[u.r][u.c][u.dir] + 1;
p[v.r][v.c][v.dir] = u;
q.push(v);
}
}
}
printf("No Soulution\n");
}
int main()
{
memset(has_edge, 0, sizeof(has_edge));
//設置約束條件,規定在某個點上,角色只能往某幾個方向走
//如下,規定(3,1)朝北的角色只能向前(F)走
has_edge[3][1][N][F] = true;
has_edge[2][1][N][F] = true;
has_edge[2][1][S][L] = true;
has_edge[2][1][W][R] = true;
has_edge[1][1][N][R] = true;
has_edge[1][1][W][L] = true;
has_edge[1][2][E][R] = true;
has_edge[1][2][W][F] = true;
has_edge[1][2][W][L] = true;
has_edge[1][2][N][R] = true;
has_edge[2][2][E][F] = true;
has_edge[2][2][E][L] = true;
has_edge[2][2][S][L] = true;
has_edge[2][2][W][F] = true;
has_edge[1][3][E][R] = true;
has_edge[1][3][N][L] = true;
has_edge[2][3][E][L] = true;
has_edge[2][3][S][F] = true;
has_edge[2][3][S][R] = true;
has_edge[3][3][S][F] = true;
solve();
return 0;
}
輸出: