问题理解
给定 n 个整数,这些整数两两相加可以得到 n(n - 1) / 2 个和。我们的目标是根据这些和找出原来的 n 个整数。如果无解,输出 "Impossible"。
关键点
-
和的性质:
- 给定的
sums数组包含了所有可能的两两相加的结果。 - 例如,对于
n = 3,sums包含(x1 + x2, x1 + x3, x2 + x3)。
- 给定的
-
推导原始数:
- 我们需要从
sums中推导出原始的n个整数。 - 一种常见的方法是从最小的和开始推导,逐步构建出所有的数。
- 我们需要从
思路提示
-
排序和:
- 首先对
sums进行排序。排序后的sums可以帮助我们更容易地找到最小的和,从而推导出原始数。
- 首先对
-
推导第一个数:
-
假设
sums中最小的和是x1 + x2,次小的和是x1 + x3,第三小的和是x2 + x3。 -
通过这些和,我们可以推导出
x1:
x1 = (sums[0] + sums[1] - sums[2]) / 2- 然后利用
x1推导出x2和x3:
x2 = sums[0] - x1 x3 = sums[1] - x1 -
-
递归推导:
- 一旦我们推导出前几个数,我们可以继续推导剩下的数。
- 例如,假设我们已经推导出
x1, x2, x3,我们可以利用这些数和sums中的其他和来推导出更多的数。
-
验证结果:
- 在推导过程中,我们需要验证推导出的数是否满足所有给定的和。
- 如果某个推导出的数不满足条件,说明推导失败,需要尝试其他可能性。
完成代码
import itertools
def solution(n, sums):
# 枚举 sums 的所有排列
for perm in itertools.permutations(sums):
# 利用 sums 中前面3个值推导出 x1
# perm[0] 是 x1 + x2, perm[1] 是 x1 + x3, perm[n-1] 是 x2 + x3
x1 = (perm[0] + perm[1] - perm[n-1]) // 2
# 利用 x1 来推导其他的 xi
x = [x1]
for i in range(n-1):
xi = perm[i] - x1
x.append(xi)
# 验证 xi 和 xj 是否满足所有 sums 条件
index = 0
valid = True
for i in range(n):
for j in range(i+1, n):
if x[i] + x[j] != perm[index]:
valid = False
break
index += 1
if not valid:
break
# 如果验证通过,返回结果
if valid:
return " ".join(map(str, sorted(x)))
# 如果所有排列都不满足,返回 "Impossible"
return "Impossible"
# 测试用例
if __name__ == "__main__":
print(solution(3, [1269, 1160, 1663]) == "383 777 886")
print(solution(3, [1, 1, 1]) == "Impossible")
print(solution(5, [226, 223, 225, 224, 227, 229, 228, 226, 225, 227]) == "111 112 113 114 115")
print(solution(5, [-1, 0, -1, -2, 1, 0, -1, 1, 0, -1]) == "-1 -1 0 0 1")
print(solution(5, [79950, 79936, 79942, 79962, 79954, 79972, 79960, 79968, 79924, 79932]) == "39953 39971 39979 39983 39989")