马踏棋盘问题(C++版)

 递归求解(回溯法求解),列出所有的解:

主要注意对各种参数的定义不要弄混,细心表达各种变量,可以在棋盘中设置墙壁,便于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 <iostream>
#include <iomanip>
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<<setw(5)<<M.b[i][j];
		}
		cout << endl;
	}
}

int main()
{
	Maze M;
	MazePath(M);
	shuchu(M);
	return 0;
}

 马踏棋盘运行结果如下:

 同样地,也可以根据其性质,改造成合适长宽的象踏棋盘,但万变不离其宗,原理均一致,弄懂了即可以不变应万变。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值