对于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 <N <17的所有其他值,它正在工作
我用一个简单的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值的最终列表,你会看到...
for i in reversed(range(len(rows))):
...
rows.pop(i)
在迭代它时,不要从列表中删除项目。
len()
只在循环的顶部计算一次,所以当你在循环执行期间缩短列表时,你最终会尝试迭代不再存在的项目。