这次京东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)发现问题,记得留言指教哦