象棋中“马”从某个位置(0,0)出发,经过K步,落在(x,y)上,有多少种方法

本文探讨了一道经典的算法题目——马在棋盘上行走的所有可能路径数量。通过暴力递归与动态规划两种方法实现解决方案,并对比了两者的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

描述:假设把整个棋盘放入第一象限,棋盘的最左下角是(0,0)位置,整个棋盘就是横坐标上9条线,纵坐标上10条线的区域,给出三个参数x,y,k;返回“马”从(0,0)位置出发,必须走K步,最终落在(x,y)上的方法数有多少种?

比如:K = 10;x = 7;y = 7  ,返回多少种方法?

解决方案:暴力递归和动态规划的思路去解决问题

1、暴力递归

1.1、图示分析:

马在一个位置可以有八种选择,总之,加到一起就可以了。

1.2核心代码分析:


public class NanDaoHorseJump {
    public static void main(String[] args) {
        int x = 7;
        int y = 7;
        int step = 10;
        System.out.println(jumpWays1(x, y, step));
    }

    /**
     * 当前来到的位置是(x,y)
     * 	还剩下rest步需要跳
     * 跳完rest步,正好跳到a,b的方法数是多少?
     * 	10 * 9
     * @param k
     * @return
     */
    private static int jumpWays1(int a, int b, int k) {
        return j1(0,0,k,a,b);
    }

    private static int j1(int x, int y, int rest, int a, int b) {
        if(x < 0 || x > 9 || y < 0 || y > 8){
            return 0;
        }
        if(rest == 0){
            return (x == a && y == b)? 1 : 0;
        }
        //马跳的8种情况相加
        int ways = j1(x - 1,y + 2,rest - 1,a,b);
        ways += j1(x - 1,y - 2,rest - 1,a,b);
        ways += j1(x - 2,y + 1,rest - 1,a,b);
        ways += j1(x - 2,y - 1,rest - 1,a,b);
        ways += j1(x + 1,y - 2,rest - 1,a,b);
        ways += j1(x + 1,y + 2,rest - 1,a,b);
        ways += j1(x + 2,y + 1,rest - 1,a,b);
        ways += j1(x + 2,y - 1,rest - 1,a,b);
        return ways;
    }

}

2、动态规划

2.1、三维数组图示:

有默认值,x轴和y轴之间,标准动态规划思想 

2.2、过程图:

2.3、核心代码如下:


public class NanDaoHorseJump {
    public static void main(String[] args) {
        int x = 7;
        int y = 7;
        int step = 10;
        System.out.println(jumpWays2(x, y, step));
    }

    /**
     * 当前来到的位置是(x,y)
     * 	还剩下rest步需要跳
     * 跳完rest步,正好跳到a,b的方法数是多少?
     * 	10 * 9
     * @param k
     * @return
     */
    private static int jumpWays2(int a, int b, int k) {
        int[][][] dp = new int[10][9][k + 1];
        dp[a][b][0] = 1;
        for(int rest = 1;rest <= k;rest++){
            for(int x = 0;x < 10;x++){
                for(int y = 0;y < 9;y++){
                    //马跳的8种情况相加
                    int ways = j2(dp,x + 2,y + 1,rest - 1);
                    ways += j2(dp,x + 2,y - 1,rest - 1);
                    ways += j2(dp,x + 1,y - 2,rest - 1);
                    ways += j2(dp,x + 1,y + 2,rest - 1);
                    ways += j2(dp,x - 2,y - 1,rest - 1);
                    ways += j2(dp,x - 2,y + 1,rest - 1);
                    ways += j2(dp,x - 1,y + 2,rest - 1);
                    ways += j2(dp,x - 1,y - 2,rest - 1);
                    dp[x][y][rest] = ways;
                }
            }
        }
        return dp[0][0][k];
    }

    private static int j2(int[][][] dp, int x, int y, int rest) {
        if(x < 0|| x > 9 || y < 0 || y > 8){
            return 0;
        }
        return dp[x][y][rest];
    }

}

两个方案执行结果如下:

到此,该到算法分享完毕,后期会有更多的解决方案和大家分享,敬请期待! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寅灯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值