0518蚂蚁暑期实习上机考试题1:数组操作
题目
小红认为一个长度为 n 的数组 a 是好的,当且仅当对于任意的 i ,均满足相等,其中数组下标 i 从 1 开始,小红每次可以对一个数加 1 或者减 1 ,求把给定的数组变成好数组的最少操作次数。
输入描述:第一行是一个整数,表示数组长度。 第二行是
个整数,第
个为
。
输出描述:一个整数,表示把给定的数组变成好数组的最少操作次数。
输入示例1:
3
3 2 1
输出示例1:
2
解释:
将数组[3,2,1]调整为[3,4,1]经过的步数最小,为2;[3,4,1]是一个好数组,满足:
输入示例2:
3
1 2 3
输出示例2:
0
解答
此题注意输入的第二句话:数组是个整数,第
个数组元素为
。
我们很容易设对于任意的 i ,都满足。对于给定的
,
需要调整到
或者
。即第 i 个元素的最小调整代价是
,总的代价就是
因此,只需从0遍历k,得到最小代价时的k,然后返回这个最小代价即可。
那么的上界应该取多少呢?注意到:
当时,可以去掉绝对值:
注意到是一个大于等于1的数,也就是说,当
时,对所有的
,
都不小于
的情形,所以只需考虑
即可。
代码实现:
import sysdef solve():# data = sys.stdin.read().split()# n = int(data[0])# a = list(map(int, data[1:]))n = 10a = [9, 2, 3, 1, 5, 8, 6, 2, 4, 7]ans = float('inf')# 枚举可能的 k 值for k in range(n):total = 0# 对每个位置计算最小操作次数for i in range(1, n + 1):# 直接计算变为 i+k 与 i-k 的代价c1 = abs(a[i - 1] - (i + k))c2 = abs(a[i - 1] - (i - k))total += min(c1, c2)ans = min(ans, total)print(ans)if __name__ == '__main__':solve()