美文网首页
马的遍历问题(打印访问象棋棋盘所有位置需要的步数)

马的遍历问题(打印访问象棋棋盘所有位置需要的步数)

作者: 疋瓞 | 来源:发表于2022-01-02 21:29 被阅读0次

    1、环境配置:

    • 系统:win10
    • 编程语言:C
    • 编译器:DevC++

    2、算法思想:

    马的遍历问题,就是希望在一个规定大小的棋盘(M*N)上面,马从第(x,y)点出发,一直遍历所有的点,打印出访问某一个点所需要的步数。按照规则马能够跳跃的方向有8种可能(如下图所示):


    马的遍历.png

    3、代码:

    #include <stdio.h>
    
    void F_1(int a[10][9],int i,int j,int r,int l,int n); //r为二维数组行数,l为二维数组列数,n为访问次数,默认传1 
    
    int main(){
        int A[10][9];
        int B[3][3];
        //二维数组初始化 
        for(int i=0;i<10;i++){
            for(int j=0;j<9;j++){
                A[i][j]=-1;
            }
        }
        //打印二维数组
        for(int i=0;i<10;i++){
            for(int j=0;j<9;j++){
                printf("%d ",A[i][j]); 
            }
            printf("\n");
        } 
        
        F_1(A,0,7,10,9,1);
        
        printf("\n");
        //打印二维数组
        for(int i=0;i<10;i++){
            for(int j=0;j<9;j++){
                if(A[i][j]!=-1)
                {
                    printf(" %d ",A[i][j]); 
                }
                else{
                    printf("%d ",A[i][j]); 
                }
            }
            printf("\n");
        } 
        
        return 0;
    }
    
    
    //遍历棋盘函数F_1 
    void F_1(int a[10][9],int i,int j,int r,int l,int n)
    {
        //起始点初始化
        if(n==1){
            a[i][j]=0;
        } 
        //先访问1点
        if(((i-2>-1)&&(i-2<r))&&((j+1>-1)&&(j+1<l))){
            if((a[i-2][j+1]==-1)||(n<a[i-2][j+1])){
                a[i-2][j+1]=n;
                F_1(a,i-2,j+1,r,l,n+1);
            }
        }
        //再访问2点
        if(((i-1>-1)&&(i-1<r))&&((j+2>-1)&&(j+2<l))){
            if((a[i-1][j+2] == -1)||(n<a[i-1][j+2])){
                a[i-1][j+2]=n;
                F_1(a,i-1,j+2,r,l,n+1); 
            }
        }
        //再访问3点
        if(((i+1>-1)&&(i+1<r))&&((j+2>-1)&&(j+2<l))){
            if((a[i+1][j+2] == -1)||(n<a[i+1][j+2])){
                a[i+1][j+2]=n;
                F_1(a,i+1,j+2,r,l,n+1); 
            }
        }
        //再访问4点
        if(((i+2>-1)&&(i+2<r))&&((j+1>-1)&&(j+1<l))){
            if((a[i+2][j+1] == -1)||(n<a[i+2][j+1])){
                a[i+2][j+1]=n;
                F_1(a,i+2,j+1,r,l,n+1); 
            }
        }
        //再访问5点
        if(((i+2>-1)&&(i+2<r))&&((j-1>-1)&&(j-1<l))){
            if((a[i+2][j-1] == -1)||(n<a[i+2][j-1])){
                a[i+2][j-1]=n;
                F_1(a,i+2,j-1,r,l,n+1); 
            }
        }
        //再访问6点
        if(((i+1>-1)&&(i+1<r))&&((j-2>-1)&&(j-2<l))){
            if((a[i+1][j-2] == -1)||(n<a[i+1][j-2])){
                a[i+1][j-2]=n;
                F_1(a,i+1,j-2,r,l,n+1); 
            }
        }
        //再访问7点
        if(((i-1>-1)&&(i-1<r))&&((j-2>-1)&&(j-2<l))){
            if((a[i-1][j-2] == -1)||(n<a[i-1][j-2])){
                a[i-1][j-2]=n;
                F_1(a,i-1,j-2,r,l,n+1); 
            }
        }
        //再访问8点
        if(((i-2>-1)&&(i-2<r))&&((j-1>-1)&&(j-1<l))){
            if((a[i-2][j-1] == -1)||(n<a[i-2][j-1])){
                a[i-2][j-1]=n;
                F_1(a,i-2,j-1,r,l,n+1); 
            }
        }
            
    }
    

    4、结果展示:

    结果1.png 结果2.png

    5、反思总结:

    • 伪代码如下:
    void init(a[m][n])//将a[m][n]初始化为值全部为“-1”的二维数组 
    void F(int a[m][n],int i,int j,int r,int l,int n)////r为二维数组行数,l为二维数组列数,n为访问次数,默认传1 。
    {
        //起始位置初始为0
        if(n==1) then a[i][j]=0;
        //访问位置1 
        if(r>(i-2)>-1&&l>(j+1)>-1) then{
            if((a[i-2][j+1]==-1)||(n<a[i-2][j+1])) then{
                a[i-2][j+1]=n;
                F_1(a,i-2,j+1,n+1);
            }
        }
        //访问位置2 
        if(r>(i-1)>-1&&l>(j+2)>-1) then{
            if((a[i-1][j+2]==-1)||(n<a[i-1][j+2])) then{
                a[i-1][j+2]=n;
                F_1(a,i-1,j+2,n+1);
            }
        }
        //访问位置3 
        if(r>(i+1)>-1&&l>(j+2)>-1) then{
            ... 
        }
        //访问位置4 
        if(r>(i+2)>-1&&l>(j+1)>-1) then{
            ... 
        }
        //访问位置5 
        if(r>(i+2)>-1&&l>(j-1)>-1) then{
            ... 
        }
        //访问位置6 
        if(r>(i+1)>-1&&l>(j-2)>-1) then{
            ... 
        }
        //访问位置7 
        if(r>(i-1)>-1&&l>(j-2)>-1) then{
            ... 
        }
        //访问位置8
        if(r>(i-2)>-1&&l>(j-1)>-1) then{
            ... 
        } 
    } 
    

    相关文章

      网友评论

          本文标题:马的遍历问题(打印访问象棋棋盘所有位置需要的步数)

          本文链接:https://www.haomeiwen.com/subject/yeltcrtx.html