京东2019春招算法工程师笔试题-牛牛下象棋(编程题3)

       这次京东2019的春招算法工程师笔试时间是2018-04-09 19:00~21:00,其中有三道编程题目,当时就做了2个,后一个时间原因就没做,就截了一个图,今天又突然看到了,练练手吧哈。

题目要求:

最近牛牛开始向犇犇老师学习下中国象棋了。犇犇老师告诉他,象棋中的“马”走日字型,如下图,红色表示马能调到的位置。

以棋盘左下角为原点,向上为y轴正方向,向右为x轴正方向,建立坐标系。牛牛想知道,棋盘左下角的马,经过K次移动之后,落在坐标系 (X, Y) 的情况有多少种。当任意一次移动后马的位置不同时,两种情况被认为不同。

因为答案可能很大,请输出情况数取模1000000007的结果。

输入描述:

输入K,一个正整数,表示移动的步数(K<=100000)

输入X, Y表示坐标且X(0<=X<=8), Y(0<=Y<=8)

题目分析:(深度优先搜索DFS,栈来实现

1、每个位置最多有8种走法,如下图。

2、走过路不能重复走,感觉如果重复走,就没完没了。

3、没走一步入栈,栈顶原始为 (X, Y) 且栈的长度为K,路径加1,然后出栈,穷举结束。

4、如栈顶元素不是 (X, Y) 且栈的长度小于K,则出栈,如果栈长度等于K且栈顶元素不为 (X, Y) ,则出栈。


Python实现:

:为了方便在代码中使用左上角为原点,向下为y轴正方向,向右为x轴正方向,建立坐标系。

# 京东2019的春招算法工程师笔试时间是2018-04-09 19:00~21:00-编程题3
# 解题思路:深度优先搜索DFS,栈来实现
# @Time   :2018/5/13
# @Author :LiuYinxing


def sumKpath(x, y, k):
    chess = [[1]*9 for _ in range(10)]  # 生成棋盘,9列(对应X轴),10行(对应Y轴)
    chess[0][0] = 0  # 标记已经走过的位置,0位已经走过,1表示未走过,可以走
    st = [[0, 0, -1]]  # 初始化栈
    sumpath = 0  # 记录找到的路径数
    while st:
        i, j, di = st[-1][0], st[-1][1], st[-1][2]  # 获取栈顶原始
        i1, j1, find = -1, -1, 0  # 下一个可能扩展的结点
        while di < 8 and find == 0:
            di += 1
            if di == 0: i1, j1 = i-2, j+1
            elif di == 1: i1, j1 = i-1, j+2
            elif di == 2: i1, j1 = i+1, j+2
            elif di == 3: i1, j1 = i+2, j+1
            elif di == 4: i1, j1 = i+2, j-1
            elif di == 5: i1, j1 = i+1, j-2
            elif di == 6: i1, j1 = i-1, j-2
            elif di == 7: i1, j1 = i-2, j-1
            if -1<i1<10 and -1<j1<9 and chess[i1][j1] == 1: find = 1
        if find == 1:
            st[-1][2] = di  # 当前栈顶的一个方向 进入下一个可走的方格
            st.append([i1, j1, -1])  # 入栈
            chess[i1][j1] = 0  # 此位置已经走过
            # ---------------------------------
            if len(st) - 1 == k:
                if st[-1][0] == y and st[-1][1] == x:
                    print(st)
                    chess[st[-1][0]][st[-1][1]] = 1  # 出栈
                    st.pop()
                    sumpath += 1  # 找到一个路径
                else:
                    chess[st[-1][0]][st[-1][1]] = 1  # 出栈
                    st.pop()
            elif st[-1][0] == y and st[-1][1] == x:  # 减枝操作
                chess[st[-1][0]][st[-1][1]] = 1
                st.pop()
            # ---------------------------------
        else:
            chess[st[-1][0]][st[-1][1]] = 1  # 出栈
            st.pop()
    return sumpath % 1000000007


if __name__ == '__main__':
    x, y, k = 0, 0, 4
    if x + y > 0:  # 分情况
        print(sumKpath(x, y, k))
    elif k > 1:
        print(sumKpath(1, 2, k-1) + sumKpath(2, 1, k-1))
    else: print(0)
发现问题,记得留言指教哦

猜你喜欢

转载自blog.csdn.net/xx_123_1_rj/article/details/80302282