递归求解(回溯法求解),列出所有的解:
主要注意对各种参数的定义不要弄混,细心表达各种变量,可以在棋盘中设置墙壁,便于debug的检查与分析,并确定各种方向(dx[8]={1,1,-1,-1,2,2,-2,-2},dy[8]={2,-2,2,-2,1,-1,1,-1};),一步步探索可行解,最后说明一点:写代码时一定要力求代码的高效性与可读性,不可将能运行作为最终目的。
以下主要构造了栈进行操作,本题可以作为一个深度了解并熟悉栈性质的题目实战。
运行代码如下:
using namespace std;
#include
#include
const int StackInitSize = 30;
const int StackInc = 10;
typedef struct position
{
int x, y;
}SElemType;
struct Maze
{
int m, n;
int b[9][9]={0};
position start;
};
struct SStack
{
SElemType *base,*top;
int stacksize;
};
bool StackInit(SStack &S)
{
S.base = new SElemType[StackInitSize];
if(!S.base) return false;
S.top=S.base;
S.stacksize=StackInitSize;
return true;
}
bool Push(SStack &S,SElemType e)
{
SElemType*base;
if(S.top-S.base==S.stacksize)
{
base=(SElemType*)realloc(S.base,(S.stacksize+StackInc)*sizeof(SElemType));
if(!base) return false;
S.base=base; S.top=S.base+S.stacksize;
S.stacksize+=StackInc;
}
*S.top=e;S.top++;return true;
}
bool DelTop(SStack &S)
{
if(S.top==S.base)
{
return false;
}
S.top--;
return true;
}
bool Pop(SStack &S,SElemType &e)
{
if(S.top==S.base)
{
return false;
}
S.top--;
e=*S.top;
return true;
}
bool GetTop(SStack S,SElemType& e)
{
if(S.top==S.base)
{
return false;
}
e = *(S.top - 1);
return true;
}
void MazeInit(Maze &M,int m,int n)
{
M.m=m;
M.n=n;
}
bool MazePath(Maze &M)
{
const int dx[8]={1,1,-1,-1,2,2,-2,-2},dy[8]={2,-2,2,-2,1,-1,1,-1};
int i,j,d,k;
for(i=1;i<=M.m;i++)
{
for(j=1;j<=M.n;i++)
{
M.b[i][j]=0;
}
}
position P,Q;
bool pass,succ;
SStack S;
StackInit(S);
MazeInit(M,5,5);
M.start.x = 1; M.start.y = 1;
Push(S,M.start);
k=1;
succ=false;
while(GetTop(S,P))
{
pass=false;
for(d=M.b[P.x][P.y]+1;d<=8;d++)
{
Q.x = P.x+dx[d-1];
Q.y = P.y+dy[d-1];
if (Q.x >= 1 && Q.y>=1 && Q.x<=M.m && Q.y<= M.n && M.b[Q.x][Q.y]==0){
pass=true;
break;
}
}
M.b[P.x][P.y]=d;
if(pass){
Push(S,Q);
k++;
if(k==M.m*M.n)
{
succ=true;
break;
};
}
else
{
M.b[P.x][P.y]=0;
DelTop(S);
k--;
}
}
if(!succ) return false;
while (Pop(S,P)) M.b[P.x][P.y]=k--;
return true;
}
void shuchu(Maze M)
{
for (int i = 1; i <= M.m ; i++)
{
for (int j = 1; j <= M.n ; j++)
{
cout<
马踏棋盘运行结果如下:
同样地,也可以根据其性质,改造成合适长宽的象踏棋盘,但万变不离其宗,原理均一致,弄懂了即可以不变应万变。