华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
Solo和koko是两兄弟,妈妈给了他们一大堆积木,每块积木上都有自己的重量。现在他们想要将这些积木分成两堆。哥哥Solo负责分配,弟弟koko要求两个人获得的积木总重量“相等”(根据Koko的逻辑),个数可以不同,不然就会哭,但koko只会先将两个数转成二进制再进行加法,而且总会忘记进位(每个进位都忘记)。如当25(11101)加11(1011)时,koko得到的计算结果是18(10010):
11001
+01011
--------
10010
Solo想要尽可能使自己得到的积木总重量最大,且不让koko哭。
3
3 5 6
第一行是一个整数N(2≤N≤100),表示有多少块积木;
第二行为空格分开的N个整数 C i ( 1 ≤ C i ≤ 1 0 6 ) C_i(1≤C_i≤10^6) Ci(1≤Ci≤106),表示第 i
块积木的重量。
如果能让koko不哭,输出Solo所能获得的积木的总重量,否则输出-1。该样例输出为11。
解释: Solo能获得重量为5和6的两块积木,5转成二级制为101,6转成二进制位110,按照koko的计算方法(忘记进位),结果为11(二进制)。Koko获得重量为3的积木,转成二进制位11(二进制)。Solo和koko得到的积木的重量都是11(二进制)。因此Solo可以获得的积木的总重量是5+6=11(十进制)。
输入:
3
3 5 6
输出:
11
这道题目属于位运算和贪心算法的结合。关键在于理解题目中“不进位二进制加法”实际上是按位异或(XOR)操作的性质,然后利用贪心的思想来最大化Solo的积木总重量。
解题思路
- 理解Koko的加法逻辑:Koko的加法实际上是二进制下的按位异或(XOR)操作。例如,25(11101)和11(1011)的异或结果是18(10010)。
- 问题转化:将问题转化为将积木分成两堆,使得两堆的异或和相等。由于异或的性质,如果所有积木的异或和为0,那么可以分成两堆异或和相等的堆;否则无法满足条件。
- 贪心策略:如果所有积木的异或和为0,那么Solo可以拿走除一块积木外的所有积木,使得剩下的那一块的异或和等于Solo拿走的堆的异或和(因为总异或和为0)。为了使Solo的总重量最大,应该拿走除最小重量积木外的所有积木。
时间复杂度
- 时间复杂度:O(N),其中N是积木的数量。只需要一次遍历即可完成异或和、总和和最小值的计算。
- 空间复杂度:O(1),只使用了常数个额外变量。
from functools import reduce
n = int(input())
weights = list(map(int, input().split()))
# 计算异或和
xor_sum = reduce(lambda x, y: x ^ y, weights, 0)
# 如果异或和不为零,说明无法分配给koko
if xor_sum != 0:
print(-1)
else:
# 否则,最大重量 = 总和 - 最小积木重量
weight_sum, min_weight = sum(weights), min(weights)
print(weight_sum - min_weight)
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。