Codeforces 891B

891B - Gluttony

题意

给出一个数字集合 (a),要求构造一个数组 (b)(a) 的某个排列,且满足对于所有下标集合的子集 (S={x_1,x_2,...,x_k}(1leq x_i leq n, 0 < k < n)),有 (sum_{i=1}^{k}a_{x_i} eqsum_{i=1}^{k}b_{x_i})

分析

不得不说,当我看到 (n) 只有 (22) 之后就跑偏了。

对于原数组中的每个数,可以直接确定它在新数组中对应下标的数。原数组中最小的数对应它最大的数,对于其它数,对应的数为刚好小于它的那个数。

解法正确性证明:分两种情况,考虑选择大小为 (k) 的子集。

  1. 所选取的子集不包括最大的数((b) 数组中),也就是说 (b) 中对应下标的数都分别小于 (a) 中的,显然和都小于。
  2. 包括最大的数((b) 数组中),这个下标是 (a) 取最小值,(b) 取最大值的下标,我们考虑补集,对于补集中的所有下标 (x_j),显然 (a_{x_j}>b_{x_j}),那么 (sum_{j=1}^{n-k}a_{x_j}>sum_{j=1}^{n-k}b_{x_j}),显然有 (sum_{i=1}^{k}a_{x_i}<sum_{i=1}^{k}b_{x_i})

这一道题又一次让我感觉到,Codeforces 真好玩!

code

input()
a = list(map(int, input().split()))
for i in a:
    print(sorted(a)[sorted(a).index(i)-1])
原文地址:https://www.cnblogs.com/ftae/p/7887393.html