为什么我的 python 函数在递归调用时不能正常工作?

时间:2021-01-15 20:39:26

标签: python-3.x recursion

我正在做之前滑铁卢 ccc 比赛的一道题(https://cemc.uwaterloo.ca/contests/computing/2020/ccc/juniorEF.pdf 题 J5) 我的代码没有按照我预期的方式工作

这是我正在使用的示例输入:

3

4

3 10 8 14

1 11 12 12

6 2 3 9

这是我目前的代码

y_size = int(input())
x_size = int(input())
mat = []

"ok".split()
for i in range(y_size):
    row = input().split()
    mat.append(row)

pos_list = [[0, 0]]
current_num = int(mat[0][0])
a = 0


def canEscape():
    global a
    global mat
    global pos_list
    global current_num
    end = y_size * x_size
    if y_size -1 * x_size -1 == current_num:
        return True
    for i in range(y_size):
        print("______")
        for j in range(x_size):
            v = (i + 1) * (j + 1)
            print(v)
            print(current_num)
            if v == current_num:
                print("ok")
                if v == end:
                    print("ok")
                a += 1
                current_num = mat[i][j]
                pos_list.append([i, j])
                canEscape()
                pos_list.pop(-1)
                a -= 1
                current_num = mat[pos_list[a][0]][pos_list[a][1]]


canEscape()

我遇到的问题是,当我再次调用它时,我希望 if v == current_num: 为真。 current_numv 都等于 8,但代码似乎继续执行 for-in 循环和 break,没有进入 if 语句。对于 for 循环的每次迭代,我都将输出打印 v 后跟 current_num 以尝试找出问题,但似乎两个变量 == 8 所以我真的不知道是什么我做错了。是我犯了一个愚蠢的错误还是我的整个程序结构错误?

1 个答案:

答案 0 :(得分:0)

我完全无法理解您的程序在做什么。这个问题涉及整数分解,我看不出你在哪里分解整数。你肯定没有理解问题的那个方面。

当您计算可以访问的单元格时,您会查看当前单元格的值。假设它是 6。6 有因数 1、2、3 和 6,因为所有这些数字都可以乘以另一个数字等于 6。因此,您可以转到单元格 (1, 6), (6, 1)、(2, 3) 和 (3, 2),因为它们是可以相乘等于 6 的数对。

此外,您永远不会将输入行转换为整数。当您附加到矩阵时,您将附加一个恰好是数字的字符串列表。您必须将它们转换为整数。

无论如何,这个程序将解决问题。我从其他线程复制并粘贴了分解算法:

n_rows = int(input())
n_cols = int(input())
mat = []

for i in range(n_rows):
    mat.append(list(map(lambda x: int(x), input().split()))) # Convert input strings to integers.

def reduce(f, l):
    # This is just needed for the factoring function
    # It's not relevant to the problem
    r = None
    for e in l:
        if r is None:
            r = e
        else:
            r = f(r, e)
    return r
    

def factors(n):
    # An efficient function for calculating factors.
    return set(reduce(list.__add__, 
                ([i, n//i] for i in range(1, int(n**0.5) + 1) if n % i == 0)))

def get_pairs(items):
    for i in range(len(items) // 2):
        yield (items[i],items[len(items) - 1 - i]) # use yield to save memory
    if(len(items) % 2 != 0): # This is for square numbers.
        n = items[len(items) // 2]
        yield (n,n)

checked_numbers = set()

def isPath(r=1, c=1):
    # check if the testing row or column is to large.
    if r > n_rows or c > n_cols:
        return False
    y = r - 1
    x = c - 1
    n = mat[y][x]
    # If we've already checked a number with a certain value we dont need to check it again.
    if n in checked_numbers:
        return False
    checked_numbers.add(n)
    # Check if we've reached the exit.
    if(r == n_rows and c == n_cols):
        return True

    # Calculate the factors of the number, and then find all valid pairs with those factors.
    pairs = get_pairs(sorted(list(factors(n))))
    # Remember to check each pair with both combinations of every pair of factors.
    # If any of the pairs lead to the exit then we return true.
    return any([isPath(pair[0], pair[1]) or isPath(pair[1], pair[0]) for pair in pairs])

if isPath():
    print("yes");
else:
    print("no");

这行得通,而且速度很快。但是,如果您的内存有限和/或数据输入量很大,您的程序很容易耗尽内存。我认为有些测试输入可能会发生这种情况,但我不确定.. 肯定有可能以使用一小部分内存的方式编写此程序,也许是通过将因子函数转换为一个使用迭代器的函数,并将 get_pairs 函数转换为以某种方式进行迭代。

我认为这个解决方案解决了他们拥有的大部分测试输入,但不会解决最后的测试输入,因为它们会非常大并且会耗尽内存。

相关问题