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
相关产品推荐
相关产品推荐

