📜  门| GATE 2017 MOCK II |问题 1(1)

📅  最后修改于: 2023-12-03 15:12:35.110000             🧑  作者: Mango

门| GATE 2017 MOCK II |问题 1

这是一道计算机科学和工程的问题,涉及到数据结构和算法的知识。

题目描述

有 $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格式,下同。