C++ !异或的操作 !

题目描述
Solo和koko是两兄弟,妈妈给了他们一大袋糖,每块糖上都有自己的重量。现在他们想要将这些糖分成两堆。分糖的任务当然落到了大哥Solo的身上,然而koko要求必须两个人获得的糖的总重量“相等”(根据Koko的逻辑),要不然就会哭的。
非常不幸的是,koko还非常小,并且他只会先将两个数转成二进制再进行加法,而且总会忘记进位。如当12(1100)加5(101)时:

 1100
+0101
——-
 1001

于是koko得到的计算结果是9(1001)。

此外还有一些例子:

5 + 4 = 1
7 + 9 = 14
50 + 10 = 56

(事实上,这正是异或运算:125=9,54=1…)
现在Solo非常贪婪,他想要尽可能使自己得到的糖的总重量最大,且不让koko哭。

解答要求
时间限制:1000ms, 内存限制:64MB

输入
输入的第一行是一个整数N(2 ≤ N ≤ 15),表示有袋中多少块糖。第二行包含N个用空格分开的整数Ci (1 ≤ Ci ≤ 106),表示第i块糖的重量。

输出
如果能让koko不哭,输出Solo所能获得的糖的总重量,否则输出“NO”。

样例
输入样例 1

3
3 5 6

输出样例 1

11

输入样例 2

5
1 2 3 4 5

输出样例 2

NO

输入样例 3

8
7258 6579 2602 6716 3050 3564 5396 1773

输出样例 3

35165

提示
Sample1中,三块糖重量为3、5、6,因为5(101)+6(110)=3(11),所以Solo拿走了重为5和6的糖,koko则得到了重为3的糖。

Sample2中五块糖,无论如何分,都无法满足koko的要求,所以NO。

Sample3中Solo拿走了前面7块糖,一共重35165。

最开始的思路是遍历所有的方法,然后算出最大值。
研究了一下异或发现,如果分得两组数异或值相等,那么这一整组数的异或值必为0,以用例一分析:

3 ^ 5
0011 ^ 0101=0110(6)
6 ^ 6 = 0

而且如果这组值能够异或均分,那么无论怎么分都可以,所以为满足要求,只需要把最小值去除,剩下的和就是Solo需要的最大值。

#include 
#include 
#include 
#include 
using namespace std;
const int maxInt = 2147483647;
int main()
{
     
	int n;
	while (cin>>n)
	{
     
		vector<int> numVec;
		int numSum = 0;
		int addSum = 0;
		int minNum = maxInt;
		while (n--)
		{
     
			int num;
			cin >> num;
			numSum ^= num;
			addSum += num;
			numVec.push_back(num);
			if (num < minNum) {
     
				minNum = num;
			}
		}
		if (!numSum){
     
			cout << addSum-minNum << ::endl;
		} else {
     
			cout << "NO" << ::endl;
		}	
	}
	
	return 0;
}

你可能感兴趣的:(C++,基本练习)