对于NOI 2018(荷兰国家信息奥林匹克),我需要解决编码问题。
我的程序从stdin接收一个介于3和17之间的偶数N。 然后,它生成具有N / 2个零和N / 2个零的数组(例如[0,0,0,1,1,1]) 然后,它按字典顺序生成该数组的所有排列,并将其存储在另一个数组中。 然后它将删除重复项,因为我生成所有排列的函数都会生成重复项。
它会删除所有不满足以下条件的所有项目:彼此相邻的相同值不得超过两个。
然后返回剩余的项目数,然后输出每个项目。
这是我的代码:
N = int(input('N:'))
def genPermutations(num, index):
if len(num) - 1 == index:
if num not in rows:
rows.append(num)
for i in range(index, len(num)):
newList = num[:]
temp = newList.pop(i)
newList.insert(index, temp)
genPermutations(newList, index + 1)
num = []
rows = []
for j in range(2):
for i in range(int(N) // 2):
if j == 0 :
num.append(0)
else:
num.append(1)
genPermutations(num, 0)
rows = list(set(map(tuple, rows)))
for i in reversed(range(len(rows))):
rows[i] = list(rows[i])
for j in range(len(rows[i]) - 2):
if rows[i][j] == 1 and rows[i][j + 1] == 1 and rows[i][j + 2] == 1:
rows.pop(i)
elif rows[i][j] == 0 and rows[i][j + 1] == 0 and rows[i][j + 2] == 0:
rows.pop(i)
print(len(rows))
for i in reversed(range(len(rows))):
string = ''
for j in range(len(rows[i])):
string += str(rows[i][j])
print(string)
现在的问题是,当我输入N = 6时,程序将返回错误。
在3
答案 0 :(得分:0)
for i in reversed(range(len(rows))):
...
rows.pop(i)
在遍历列表时不要从列表中删除项目。
len()
在循环的顶部仅计算一次,因此,在循环执行期间缩短列表时,最终会尝试迭代不再存在的项目。
答案 1 :(得分:0)
我用简单的print
语句跟踪了问题:
for i in reversed(range(len(rows))):
rows[i] = list(rows[i])
for j in range(len(rows[i]) - 2):
print("i=", i, "j=", j, len(rows), "rows;", len(rows[0]), "cols")
if rows[i][j] == 1 and rows[i][j + 1] == 1 and rows[i][j + 2] == 1:
rows.pop(i)
输出:
i= 19 j= 0 20 rows; 6 cols
i= 19 j= 1 20 rows; 6 cols
i= 19 j= 2 20 rows; 6 cols
i= 19 j= 3 19 rows; 6 cols
...这是您的问题。您仍在尝试处理该行时从表中删除了该行。执行此操作时,还需要从break
循环中退出j
。在两个子句中:
if rows[i][j] == 1 and rows[i][j + 1] == 1 and rows[i][j + 2] == 1:
rows.pop(i)
break
elif rows[i][j] == 0 and rows[i][j + 1] == 0 and rows[i][j + 2] == 0:
rows.pop(i)
break
这将产生14个排列的预期答案。
这仅在N=6
上失败,因为这是唯一删除最终排列的集合。打印出每个N值的最终列表,您会看到...