89 分糖果
作者: xxx时间限制: 10S章节: 一维数组
问题描述 :
肖恩和帕特里克是兄弟,他们从他们的父母那里得到了很多糖果。每一块糖具有一个正整数的价值,孩子们希望分他们得到的糖果。首先,肖恩将这些糖果分成两堆,并选择一堆给帕特里克。然后,帕特里克将尝试计算每堆的价值,其中每堆的价值是那堆糖果价值的总和,如果他觉得没有平等的价值,他将开始哭了起来。
不幸的是,帕特里克太小了,所以不能正确的计算。他只会二进制无进位的加法。比如说,他想算12(二进制为1100)加5(二进制为101),他会把最右边的两位加法算正确,但是第三位会忘记进位。(即0+0=0,0+1=1,1+0=1,1+1=0)
因此,帕特里克算12加5的结果为9。下面几个是帕特里克算的结果:
5 + 4 = 1
7 + 9 = 14
50 + 10 = 56
肖恩数学很好,他想得到价值总和更高的糖果并且不让他的弟弟哭。如果可能,他会分成两个非空的糖果袋,让帕特里克认为,双方都有相同的值的糖果。给你每一袋糖果每一块糖果的价值,我们想知道是否可能让帕特里克相信他们得到糖果价值的总量是相同的。如果可能计算出肖恩能得到的最大的价值。
输入说明 :
第一行输入T(1<T<10),表示接下来输入T组测试数据。
每组测试数据占一行,每行包含以下数据,N C1 C2 … Cn(其中N(2 ≤ N ≤ 10)代表从父母那里得到糖果的总数,C(1 ≤ Ci ≤ 100)代表每块糖果的价值)
输出说明 :
若不能输出NO,若能则输出肖恩得到的最大的价值。
输入范例 :
2
5 1 2 4 5 8
3 3 5 6
输出范例 :
NO
11
+++++++++++++++++++++++++这是分割线++++++++++++++++++++++++
一开始我一点思路也没有,看了一些大佬的代码才知道这道题得用异或做(我第一次用异或做题……)
代码
/*
T89 分糖果
算法概述:这个题的关键是“二进制无进位的加法”实际上说的是异或,也就是
二进制中的“同0异1”的操作。
先判断所有糖果价值的异或(符号为^)是不是0,
如果是0,那么肯定能分成“价值”
相等的两堆(因为两个相同二进制数的异或为0),而如果异或结果为0,那么肖恩
能得到的最大的价值的情况一定是“一堆放那个最小价值的,另一堆放除了最小以外的”
因为如果所有糖果价值的异或为0,那么【最小的糖果价值】和【除了最小之外的其他
糖果】的一定是“价值”(也就是二进制)相等的(因为如果”价值“不等的话所有
糖果的异或不可能是0),所以只需要把最小的那个揪出来把其他的加起来就是肖恩
能得到的最大的价值了
如果是1,那么不可能分成“价值”相等的两堆
*/
#include<stdio.h>
#define MAX_SIZE 12
int main() {
int i = 0;
int sum = 0;// 糖果真正价值总和
int min = 105;
int T = 0, N = 0;
int C[MAX_SIZE] = {0};
int xorSum = 0;// 糖果价值的异或和
scanf("%d", &T);
while (T--) {
min = 105, sum = 0;
scanf("%d", &N);
scanf("%d", &C[0]);
sum += C[0];
if (C[0] < min)
min = C[0];
xorSum = C[0];
for (i = 1; i < N; i++) {// 累加糖果价值的异或
scanf("%d", &C[i]);
sum += C[i];
xorSum ^= C[i];
if (C[i] < min)
min = C[i];// 更新最小
}
if (xorSum == 0)// 能分成价值相等的两堆
printf("%d\n", sum - min);
else
printf("NO\n");
}
return 0;
}
从这道题我学到了:
- 利用异或来解决一些看起来很复杂的问题,比如这里的两堆相等