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
解答思路:
这题一开始根本没有思路,因为不知道异或这个概念。然后去网上搜了搜这道题,不得不说有的人素质是真的差。搜到了好几个博文都是一模一样但不同人发的。原封不动直接照抄。你抄 N M 呢,真是垃圾。
简单说下我理解的这题的做法。首先看到11得0,00得0,10 01得1。得看出来两数相同则运算结果为0这个规律,这恰好是C语音中异或的概念,运算符:^ 。
其次,这题把所有输入数异或起来,若结果为0,则有分的方法,不然则没有。可以这样理解,如果结果不为0。把若干个输入任意分为两堆,再把这两堆的结果异或起来结果不为0。则说明 不可能存在“结果相等”的两堆(因为相等异或必为0)。所以这时肯定没法分 输出 NO。而若结果为0。则我们把最小值提取出来即可,因为最小值与 除最小值之外所有值之“和” 异或的结果为0。
十进制数在运算时自动转换成二进制。所以也不需要额外进制转换。
AC代码
#include <cstdio>
int main(){
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
int temp;
scanf("%d",&temp);
int sum=temp; //sum为异或和 account为正常和
int min=temp;
int account=temp;
n--;
while(n--)
{
scanf("%d",&temp);
sum=sum^temp;
account+=temp;
if(temp<min)
{
min=temp;
}
}
if(sum)
{
printf("NO\n");
}
else
{
printf("%d\n",account-min);
}
}
}