You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

USACO变换程序异常求助:输出随打印语句变化

USACO 变换问题代码排错

我在解决USACO变换问题时卡壳了,怎么都找不到代码里的bug。已经实现了所有变换步骤,自认为rotate、reflect这些函数逻辑没问题,但运行结果和预期对不上。更诡异的是,加了某些print语句后,程序输出居然会变,完全不符合常理。以下是我的代码:

def rotate(grid):
    new = grid.copy()
    l, r = 0, len(grid) - 1
    while l < r:
        for i in range(r - l):
            top, bottom = l, r

            # save the topleft
            topLeft = grid[top][l + i]

            # move bottom left into top left
            new[top][l + i] = grid[bottom - i][l]

            # move bottom right into bottom left
            new[bottom - i][l] = grid[bottom][r - i]

            # move top right into bottom right
            new[bottom][r - i] = grid[top + i][r]

            # move top left into top right
            new[top + i][r] = topLeft
        r -= 1
        l += 1
    return new

# reverse each row individually
def reflect(grid):
    new = []
    rows = len(grid)
    for i in range(rows):
        new.append(grid[i][::-1])
    return new

with open('transform.in', 'r') as fin, open('transform.out', 'w') as fout:
    n = int(fin.readline().strip())
    before = [list(fin.readline().strip()) for _ in range(n)]
    after = [list(fin.readline().strip()) for _ in range(n)]

    if after == rotate(before):
        print('1')
        fout.write("1\n")
    elif after == rotate(rotate(before)):
        print('2')
        fout.write("2\n")
    elif after == rotate(rotate(rotate(before))):
        print('3')
        fout.write("3\n")
    elif after == reflect(before):
        print('4')
        fout.write("4\n")
    elif (after == rotate(reflect(before)) or
        after == rotate(rotate(reflect(before))) or
        after == rotate(rotate(rotate(reflect(before))))):
        print('5')
        fout.write("5\n")
    elif after==before:
        print('6')
        fout.write("6\n")
    else:
        print('7')
        fout.write("7\n")

核心问题:浅拷贝导致的引用污染

你的rotate函数里,new = grid.copy()是浅拷贝。因为grid是二维列表(列表嵌套列表),copy()只会复制外层列表的结构,里面的每个子列表还是和原grid共享内存引用。这意味着你修改new的元素时,实际上也在修改原grid的元素——比如第一次调用rotate(before)时,已经悄悄修改了before本身,后续判断rotate(rotate(before))时,用的是被篡改过的before,结果自然错误。而添加print语句时,可能会触发列表的求值顺序变化,导致引用修改的时机改变,从而出现输出不同的诡异现象。

修复方案

1. 修复rotate的拷贝逻辑

把new = grid.copy()替换成深拷贝,确保每个子列表都是独立副本:

def rotate(grid):
    # 深拷贝二维列表,避免引用污染
    new = [row.copy() for row in grid]
    l, r = 0, len(grid) - 1
    while l < r:
        for i in range(r - l):
            top, bottom = l, r
            topLeft = grid[top][l + i]
            new[top][l + i] = grid[bottom - i][l]
            new[bottom - i][l] = grid[bottom][r - i]
            new[bottom][r - i] = grid[top + i][r]
            new[top + i][r] = topLeft
        r -= 1
        l += 1
    return new

2. 可选:用更简洁可靠的旋转逻辑

手动循环实现旋转容易出错,可以用Python的内置语法实现顺时针90度旋转,逻辑更清晰:

def rotate(grid):
    # 顺时针旋转90度:先反转行顺序,再转置矩阵
    return [list(col) for col in zip(*grid[::-1])]

这个写法完全避免了手动处理层循环的bug,更易维护。

3. 验证其他逻辑

你的reflect函数是正确的,每行反转的逻辑符合题目要求的水平翻转。主函数的判断顺序也符合USACO题目要求(必须按优先级从1到7判断)。

修复后再运行测试用例,就能得到正确结果了。


内容的提问来源于stack exchange,提问作者Michael Granger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 14:57:05