【dfs解决数字游戏问题】

数字游戏

提示:通过深度优先搜索(DFS)来解决

// 问题描述
在课堂上,老师与同学们玩了这样一个游戏: 老师先在黑板上写下了一个数x,之后让n-1个同学依次选择如下两种操作之一进行操作:
1.在黑板上写下5x,即写下x的五倍这个数;
2.当且仅当x是偶数时可以在黑板上写下x/2这个数字。
每个同学操作之后,黑板上新写下的数变成下一个同学的数x。不过同学们写数字时都是比较乱的。下课之后,你从隔壁班走过来看见黑板上一共有n个数字而不知道它们被写下来的顺序,只知道老师写的数字是X。

你的任务是找到一个合法的被写下的数字顺序。如果有多个答案符合要求,
请输出字典序最小的那个序列。

输入描述
第一行两个正整数n,x,表示黑板上的数字个数和老师写的数字;
第二行n个正整数1,2...n.表示黑板上这n个数。老师写的数字也在这里面。
1 < n <80, 1 < ai < 10^18

输出描述
输出一行n个数,表示字典序最小的合法的序列。

样例输入‘’
5 16
8 20 16 10 4
样例输出
16 8 4 20 10

这个问题可以通过深度优先搜索(DFS)来解决。我们可以从最后一个数开始往前还原整个过程。对于每个数,它只有两个可能的来源:通过乘以 5 或者通过除以 2 得到。我们可以依次尝试这两种可能性,然后递归还原整个序列。为了确保输出的是字典序最小的序列,我们可以在递归的时候选择优先使用 2 的操作。

# ACM模式
def restore_sequence(n, x, numbers):
    result = [0] * n

    def dfs(i, current):
        nonlocal result
        if i == n:
            result = current[:]
            return

        div2 = current[-1] // 2 if current[-1] % 2 == 0 else None
        mul5 = current[-1] * 5

        # 优先尝试除以 2
        if div2 in numbers:
            dfs(i + 1, current + [div2])
        # 如果除以 2 不满足条件,再尝试乘以 5
        elif mul5 in numbers:
            dfs(i + 1, current + [mul5])

    # 从最后一个数开始还原
    dfs(1, [x])

    return result

# 示例
input_data = input().split()
n_value = int(input_data[0])
x_value = int(input_data[1])
numbers_value = list(map(int, input().split()))

sequence_result = restore_sequence(n_value, x_value, numbers_value)
print(" ".join(map(str, sequence_result)))

你可能感兴趣的:(深度优先,算法,python,经验分享)