数组符号翻转操作求最大和及最少操作次数问题求助
问题分析
要解决这个问题,我们需要完成两个核心目标:
- 计算数组的最大可能和:将所有元素转为绝对值后求和就是最大和——翻转负数符号能最大化总和,0的符号翻转不影响结果。
- 计算达成最大和的最少操作次数:合并连续的负数块(包括被0分隔的负数块,因为翻转包含0的区间不会改变0的值,却能减少操作次数),但不能将正数块包含在翻转区间内(否则会把正数转为负数,需要额外操作恢复,反而增加次数)。
解法思路
- 最大和计算:直接累加数组中每个元素的绝对值即可。
- 最少操作次数计算:
- 遍历数组,跳过所有0元素。
- 统计连续的负数块数量:每当遇到新的负数块(当前元素是负数,且前一个非零元素不是负数),操作次数加1;遇到正数时,标记当前不在负数块中。
代码实现
def main(): import sys input = sys.stdin.read().split() n = int(input[0]) arr = list(map(int, input[1:n+1])) max_sum = sum(abs(x) for x in arr) min_ops = 0 in_neg_block = False for num in arr: if num == 0: continue is_negative = num < 0 if is_negative and not in_neg_block: min_ops += 1 in_neg_block = True elif not is_negative: in_neg_block = False print(max_sum, min_ops) if __name__ == "__main__": main()
代码说明
- 使用
sys.stdin.read()读取输入,避免多次IO操作,提升处理大数组(如2×10⁵元素)的速度,符合时间限制要求。 max_sum通过生成器表达式计算所有元素的绝对值之和,高效简洁。min_ops统计逻辑:in_neg_block标记当前是否处于连续负数块中。- 遇到0直接跳过,因为翻转0不影响结果,也不需要单独操作。
- 遇到新负数块时操作次数加1并更新标记;遇到正数时重置标记,退出负数块状态。
示例验证
对于输入:
4 -1 0 -2 -1
- 最大和为
|-1| + |0| + |-2| + |-1| = 1+0+2+1=4。 - 遍历数组时,第一个非零元素是-1(新负数块,操作次数+1),后续的-2、-1属于同一块,0被跳过,最终操作次数为1,与示例输出一致。
内容的提问来源于stack exchange,提问作者Passion TowardsCloud
相关产品推荐
相关产品推荐

