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

2022-01-02  本文已影响0人  疋瓞

1、环境配置:

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{
        ... 
    } 
} 
上一篇 下一篇

猜你喜欢

热点阅读