分积木 - 华为OD机试刷题记录
题目描述
Solo和koko是两兄弟,妈妈给了他们一大堆积木,每块积木上都有自己的重量。
现在他们想要将这些积木分成两堆。哥哥Solo负责分配,弟弟koko要求两个人获得的积木总重量“相等”(根据Koko的逻辑),个数可以不同,不然就会哭,但koko只会先将两个数转成二进制再进行加法,而且总会忘记进位(每个进位都忘记)。如当25(11101)加11(01011)时,koko得到的计算结果是18(10010):
11001
+01011
--------
10010
Solo想要尽可能使自己得到的积木总重量最大,且不让koko哭。
输入描述
第一行是一个整数N(2≤N≤100),表示有多少块积木;
第二行为空格分开的N个整数Ci(1≤Ci≤10^6),表示第i块积木的重量。
输出描述
如果能让koko不哭,输出Solo所能获得积木的最大总重量;否则输出“NO”。
用例1
输入
3
3 5 6
输出
11
参考题库
实现思路
- 不进位的加法其实就是
异或计算
。 - 按照题目要求最终弟弟和哥哥 分的积木重量的异或和 要想相等,假设为x, 那么所有积木的异或和
x ^ x =0
,所有积木的异或和必须为 0, 否则输出NO. - 另外一个数学定理
x ^ 0 = x
(交换律),我们的目的是让各个获得最多重要的苹果,所以给弟弟分一个最小重量积木 就行。
实现代码
#include<iostream>
#include<vector>
#include<string>
#include <utility>
#include <sstream>
#include<algorithm>
#include<list>
#include<queue>
#include<map>
#include<set>
using namespace std;
int main() {
int n;
int minValue = 10000009;
// 记录异或计算结果
int sum = 0;
// 记录实际重量和
int totalWeight = 0;
cin >> n;
for (int i = 0; i < n; i++) {
int tmp;
cin >> tmp;
sum ^= tmp;
minValue = min(minValue, tmp);
totalWeight += tmp;
}
// 不能平分
if (sum != 0) {
cout << "NO";
} else {
cout << totalWeight - minValue;
}
return 0;
}
#华为OD##华为OD2025A卷#