过河卒问题—Python题解

P1002过河卒问题

  • 题目
    • 出现的问题
  • DFS
    • 出现的BUG
  • DP
    • 出现的BUG

题目

题目描述
棋盘上A点有一个过河卒,需要走到目标B点。卒行走的规则:可以向下、或者向右。同时在棋盘上CC点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。

棋盘用坐标表示,A点(0,0)、B点(n,m)(n, m为不超过20的整数),同样马的位置坐标是需要给出的。

现在要求你计算出卒从A点能够到达B点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
过河卒问题—Python题解_第1张图片
输入格式
一行四个数据,分别表示B点坐标和马的坐标。

输出格式
一个数据,表示所有的路径条数。

输入输出样例
输入 #1 复制
6 6 3 3
输出 #1 复制
6
说明/提示
结果可能很大!

出现的问题

由于后面的数据时间超时,才发觉要用动态规划解决此问题
行走的规则只能右下方前进

DFS

// An highlighted block
#!/usr/bin/env python 
# -*- coding:utf-8 -*-

count = [0]
goitem = [[0,0],[1,2],[1,-2],[2,1],[2,-1],[-1,2],[-2,1],[-2,-1],[-1,-2]]
goitem2 = [[0,1],[1,0]]


def getNotPass(mx,my,bx,by,notpass):
    for item in goitem:
        tx = mx + item[0]
        ty = my + item[1]
        if tx >= 0 and tx <= bx and ty >= 0 and ty <= by:
            notpass[tx][ty] = 1


def drawNotPass(notpass):
    for item in notpass:
        print(item)

def dfs(x, y, dx, dy, notpass,book):
    if x == dx and y == dy:
        count[0] = count[0] + 1
        return
    for item in goitem2:
        tx = x + item[0]
        ty = y + item[1]
        if tx >= 0 and tx <= bx and ty >= 0 and ty <= by:
            if notpass[tx][ty] == 0 and book[tx][ty] == 0:
                book[tx][ty] = 1
                dfs(tx, ty, dx, dy, notpass, book)
                book[tx][ty] = 0



if __name__ == '__main__':
    bx, by, mx, my = [int(i) for i in input().split(" ")]
    notpass = [[0]*(by+1) for i in range(bx+1)]
    book = [[0]*(by+1) for i in range(bx+1)]
    book[0][0] = 1
    getNotPass(mx,my,bx,by,notpass)
    # drawNotPass(notpass)
    dfs(0,0,bx,by,notpass,book)
    print(count[0])

出现的BUG

由于语法不太熟练,对于全局变量掌握不太好。这里采用的是列表传递全局变量,在之后再更改。

  1. 当到最后终点的时候一定要返回return!!
  2. 标记已访问变量的book数据不要忘了
  3. 是否越界一定要判断

DP

#!/usr/bin/env python 
# -*- coding:utf-8 -*-

count = [0]
goitem = [[0,0],[1,2],[1,-2],[2,1],[2,-1],[-1,2],[-2,1],[-2,-1],[-1,-2]]

def getNotPass(mx,my,bx,by,notpass):
    for item in goitem:
        tx = mx + item[0]
        ty = my + item[1]
        if tx >= 0 and tx <= bx and ty >= 0 and ty <= by:
            notpass[tx][ty] = 1

def drawNotPass(notpass):
    for item in notpass:
        print(item)

def dp(x, y, dx, dy, notpass,dpbook):
    for i in range(dx+1):
        for j in range(dy+1):
            if i == 0 and j == 0:
                continue
            if notpass[i][j] == 0:
                ta = 0 if i == 0 else dpbook[i-1][j]
                tb = 0 if j == 0 else dpbook[i][j-1]
                dpbook[i][j] = ta + tb
    return dpbook[dx][dy]




if __name__ == '__main__':
    bx, by, mx, my = [int(i) for i in input().split(" ")]
    notpass = [[0]*(by+1) for i in range(bx+1)]
    dpbook = [[0]*(by+1) for i in range(bx+1)]
    dpbook[0][0] = 1
    getNotPass(mx,my,bx,by,notpass)
    # drawNotPass(notpass)
    ans = dp(0,0,bx,by,notpass,dpbook)
    print(ans)

出现的BUG

  1. 对于Python的range数据边界判断
  2. 对于0,0这个点不要被覆盖
    可以取max,或者第一行先直接赋值

你可能感兴趣的:(过河卒问题—Python题解)