处理负数个数的奇偶性
:如果负数个数为奇数,且
n
是偶数,则最终会剩下一个负数,我们通过保留一个最小的绝对值来让负数对结果的影响最小化。
计算最大和
:根据负数个数的奇偶性和数组中是否有0的情况,计算能达到的最大和。
参考代码
# 读取输入的整数n,表示数组的长度为2n-1 n = int(input()) # 读取数组a的元素,使用map函数将输入的字符串转换为整数列表 a = list(map(int, input().split()))
# 创建一个新列表b,其中的元素是数组a中每个元素的绝对值,这个列表还要进行排序 b = sorted(abs(x) for x in a)
# 初始化答案变量ans # 如果原数组中包含0或者n是奇数(可以保证经过操作后所有数都为正) if0in a or n % 2 == 1: ans = sum(b) # 直接将b中所有元素求和,因为可以使所有元素为正
else: # 统计原数组中负数的个数 neg_c = sum(1for x in a if x 0) # 如果负数个数为奇数,n为偶数时,无法通过取反操作消除所有负数 if neg_c % 2 == 1: ans = sum(b) - 2 * b[0] # 将最小的元素保持为负,其他元素取为正 else: ans = sum(b) # 负数个数为偶数,可以通过操作使所有元素为正
# 读取输入的整数n,表示树的节点数 n = int(input()) # 读取节点的权值,前面加一个0是为了使数组的索引与节点编号对应(节点从1开始编号) a = [0] + list(map(int, input().split()))
# 创建图的邻接表表示,多出的一个用于从1开始索引 g = [[] for _ in range(n + 1)]
# 初始化变量ans,用来记录总的操作次数 ans = 0
# 读取n-1条边的信息,构建无向图 for _ in range(n - 1): x, y = map(int, input().split()) g[x].append(y) g[y].append(x)
defdfs(u, fa): # 初始化子节点权值之和为0 s = 0 # 遍历节点u的所有邻接节点 for v in g[u]: if v == fa: # 跳过父节点,避免回溯 continue # 递归计算子树v的权值和,累加到s上 s += dfs(v, u) # 如果子节点权值之和大于当前节点权值,需要增加当前节点的权值
if s > a[u]: global ans # 使用全局变量ans ans += s - a[u] # 增加的操作次数为子节点权值之和与当前节点权值的差 a[u] = s # 更新当前节点的权值 return s + a[u] # 返回以当前节点为根的子树的总权值
# 从根节点1开始递归 dfs(1, 0) # 输出最少需要的操作次数 print(ans)
小F的矩阵染色方案
题目描述
解题思路
基本思路
:我们需要通过贪心的方法在矩阵中先放置
x
个
2 x 2
正方形,并且在剩余的空位放置
y
个
1 x 1
正方形。由于最多可以使用四种颜色,并且需要避免同色相邻,所以我们可以通过交替使用
a
,
b
,
c
,
d
四种颜色来填充矩阵。
放置
2 x 2
正方形
:我们首先从矩阵的左上角开始,优先放置
x
个
2 x 2
的正方形。每次放置一个
2 x 2
的正方形时,可以根据当前行号和列号的奇偶性交替使用
a
和
b
两种颜色,或者其他颜色,确保颜色不会冲突。
放置
1 x 1
正方形
:在放置完
2 x 2
正方形后,剩下的未被染色的格子放置
y
个
1 x 1
的正方形。在放置每一个
1 x 1
正方形时,我们需要确保它的颜色与其左边和上边的颜色不同。
无解判断
:如果矩阵的大小无法容纳
x
个
2 x 2
的正方形(即可放置的
2 x 2
正方形的数量小于
x
),则返回
-1
表示无解。