【过河卒】回溯算法保姆式解题

11 篇文章 1 订阅
8 篇文章 0 订阅

目录

1.简介

2.分析

3.代码实现

3.1变量的声明

3.2判断马眼睛的位置

3.3进行遍历

 4.完整代码 

5.总结


1.简介

        象棋是作为中华民族的瑰宝,其中映射了很多数学问题。卒在过河后可以前进、右移动。马则可以走日字。现在有一道题目。棋盘上 A (0,0)点有一个过河卒,需要走到目标B(n,m) 点。同时在棋盘上 C(x,y)点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点89。因此称之为“马拦过河卒”。范围如下n>=1,m<=20,x>=1||x<=20,y>=1||y<=20。

2.分析

        (1)首先我们需要分析出不能落子的点及控制点。控制点与马的距离是根号五,所以在后期回溯时候我们用当前坐标与马之间的距离作比较如果等于根号五则舍弃。

        

        (2)在计算方案时候我们运用一个最基本的数学思维,所有路径的情况和就是总路径

如下图进行分析。最后到达B点的最短路径情况就是相邻两点的和。所以每次我们只要累加两个角上的路径值就可以了。

         

3.代码实现

3.1变量的声明

        (1)声明一个二维数组num[ i ] [ j ]来表示他的路线条数

        (2)声明两个变量x,y来表示终点坐标

        (3)声明两个变量a,b来表示马的位置

        (4)声明两个变相i,j来表示实际坐标

       

    

3.2判断马眼睛的位置

        根据我们的分析可以根据距离来确定是否为马眼。

if (((a-i)*(a-i)+(b-j)*(b-j)==5)||(i==a&&j==b))//判断卒是否走到了马眼
        

3.3进行遍历

        (1)我们首先考虑特殊情况就是边界的行和列,他们只有一种走法所以我们先对其进行求解,代码如下

        

    for (  i= 0; i < x; i++)
    {
        num[i][0]=1;
    }
    for ( j = 0; j < y; j++)
    {
        num[0][j]=0;
    }

           (2)然后就到了我们的核心算法,对中心区域进行求解。由分析可知,卒只有两个方向可以走。则推出该公式。

num[i][j]=num[i-1][j]+num[i][j-1];
//此时i,j均位于边缘所以采用减法
       


for ( i = 1; i <= x; i++)
    {
        for ( j = 1; j <= y; j++)
        {
            if (((i-a)*(i-a)+(j-b)*(j-b)==5)||(i==a&&j==b))//判断卒是否走到了马眼
                num[i][j]=0;
                else num[i][j]=num[i-1][j]+num[i][j-1];
                
        }
        
    }

 4.完整代码 

#include<stdio.h>
int main(int argc, char const *argv[])
{
    
    int x,y,a,b,i,j;//x,y表示终点坐标,a,b表示马的坐标,i,j表示行走的坐标(i是行,j是列)
    int num[i][j];//数组num表示路径数

    scanf("%d%d",&x,&y);
    scanf("%d%d",&a,&b);
    for (  i= 0; i <= x; i++)
    {
        num[i][0]=1;
    }
    for ( j = 0; j <= y; j++)
    {
        num[0][j]=1;
    }


    
    for ( i = 1; i <= x; i++)
    {
        for ( j = 1; j <= y; j++)
        {
            if (((i-a)*(i-a)+(j-b)*(j-b)==5)||(i==a&&j==b))//判断卒是否走到了马眼
                num[i][j]=0;
                else num[i][j]=num[i-1][j]+num[i][j-1];
                
        }
        
    }
    printf("%d",num[x][y]);//num数组中存储了所有的路径,我们只是取出看其中x,y我们所需要的坐标的路径数。

    
    return 0;
}

5.总结

        1.注意本方法实际上求出了到达每一个点的方案个数,然后通过选择我们需要的坐标(x,y)来取出我们所需要的路径解。

        2.判断马是否在马眼上的,如果在马眼上则经过该点所有方案记为0.

        3.本方法是按行进行计算的。

  • 22
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值