📅  最后修改于: 2023-12-03 15:12:35.110000             🧑  作者: Mango
这是一道计算机科学和工程的问题,涉及到数据结构和算法的知识。
有 $n$ 个人排成一列,每个人都有一个独特的编号 $i$,编号从 $1$ 到 $n$。现在,$n-1$ 个门连在一起构成了一个闭合的环,每个门连向两个不同的人。对于每个人 $i$,钥匙的编号是 $i$,锁的编号是他前面的人的编号,但是如果 $i=1$,他的锁编号是 $n$。
我们称一把钥匙逆时针或顺时针匹配一个锁,如果能够顺时针或逆时针依次将钥匙和锁配对。
现在,假设有 $n$ 把钥匙和 $n$ 个锁在一个安全的箱子里,每个钥匙编号和每把锁的编号相匹配。目标是找到一个按照钥匙和锁的匹配方案的排列,使得每个人都能够用他的钥匙匹配他的锁。因此,如果钥匙 $i$ 逆时针匹配锁 $j$,不同于锁 $i$,我们就将 $i$ 放置在 $j$ 左边,否则我们就 放置 $i$ 在 $j$ 右边。
编写一个程序,给定 $n$ 和门的连接方式,计算并输出按照钥匙和锁的匹配方案的排列。
第一行包含一个整数 $t$,表示共有 $t$ 组数据。 每组数据包括两行。第一行包含一个整数 $n$,表示人的数量。第二行包含 $n-1$ 个整数 $a_2,a_3,\ldots,a_n$,表示门的连接方案。
对于每个测试数据,输出一行,表示计算并输出按照钥匙和锁的匹配方案的排列。
2 5 1 2 2 3 6 2 3 4 5 1
1 5 4 3 2 5 6 2 3 4 1
对于第一组数据,我们可以将环视为一个数组。对于每个人来说,他的钥匙就是他的编号,他的锁要么是他前面的人的编号,要么是 $n$。我们需要确定每个人的最终位置。
我们先创建一个计数器 $p$,开始时为 $1$。我们从 $1$ 开始,将钥匙放到对应的锁上。然后我们将锁对应的位置作为下一个人的位置,递归处理下一个人。
对于第二组数据,我们可以使用一个循环来找到门的连接方式的终点。我们找到这个点后,我们可以将环从这里切开,然后将左半部分和右半部分递归地处理。
def determine_position(n, doors):
keys = [i for i in range(1, n+1)]
locks = [None for _ in range(n)]
for i in range(n-1):
if locks[doors[i]-2] is None:
locks[doors[i]-2] = keys[i]
else:
locks[i] = keys[i]
if locks[n-2] is None:
locks[-1] = keys[-1]
else:
locks[0] = keys[-1]
p = locks.index(n)
for i in range(n):
pos = (i + p) % n
if locks[pos] != keys[i]:
p = pos
break
result = [None for _ in range(n)]
for i in range(n):
pos = (i + p) % n
result[pos] = keys[i]
return result
t = int(input())
for _ in range(t):
n = int(input())
doors = list(map(int, input().split()))
result = determine_position(n, doors)
print(*result)
代码返回的是markdown格式,下同。