寒假菜鸟系列学习题

第一天,记下异或题

Problem F

Time Limit : 3000/2000ms (Java/Other)   Memory Limit : 65535/102400K (Java/Other)
Total Submission(s) : 64   Accepted Submission(s) : 35
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

Problem Description

笨蛋君得到了一堆糖果,他想将糖果分给他的两个好朋友BD666和BD888。他在地上放n个糖果,每个糖果都有它的价值,分别是v1,v2,v3,v4...vn。笨蛋君先让BD666在地上捡起一部分糖果(不能全捡),随后BD888捡起剩下的全部糖果。然后笨蛋君会检测两人手中糖果的总价值是不是相等。要注意的是笨蛋君是用异或操作来看一个人获得的总价值的。比如BD666捡了3块价值为v1,v2,v3的糖果,笨蛋君就认为他获得的价值是v1 xor v2 xor v3。如果BD666和BD888获得的总价值不相等的话,笨蛋君就会认为BD666破坏了分配的公平性。
然后问题就来了,BD666想问你在不破坏分配公平的情况下,自己能获得的最大的糖果数量是多少。
PS: 异或运算即C++中的“^ ”运算符,特点是按位运算,相同为0,不同为1,例如(1100)2^ (1010)2==(0110)2

Input

输入第一行是一个正整数T,表示有T组数据(1≤T≤100 )。
对于每组数据,第一行是一个正整数n(2≤n≤100000 )
第二行包含n个正整v1, v2, v3, v4...vn. (v i<2 31 )

Output

输出BD666所能获得的最大糖果数量,如果BD666无论如何都不能让笨蛋君满意的话(即破坏了分配的公平性),输出-1。

Sample Input

2
2
1 2
2
1 1

Sample Output

-1
1
#include<set> 
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
#define rep(i,a,b) for(i=a;i<=b;i++)
#define rec(i,a)   for(i=0;i< a;i++)
#define N 100000 +  10
#define Q 1000   +  10
#define P 100    +  1
using namespace std;
__int64 a[N]={0}; 
int main()
{
    int T;
    int n;
    int i,j;
    scanf("%d",&T);
    for(int cnt=1;cnt<=T;cnt++)
    {
        scanf("%d",&n);
        rec(i,n)scanf("%I64d",&a[i]);
      __int64 result=0;
        rec(i,n)
        {
            result^=a[i];
        } 
        if(result==0)
        {
            printf("%d\n",n-1);
        }
        else printf("-1\n");
        memset(a,0,sizeof a);
    }
return 0;
}
理解方法:我们假设某种分配方式,使得两个玩家具有同等价值,记为value(1)与value(2)。那么此时value(1)==value(2)
但是这不一定是最优解,因为相等的数异或为0,把玩家2的数都给玩家1,那么value(1)^value(2)==0;此时两个人都是0.但是题目要求
一个人不能全取走。这n个数异或结果为0,那么一定存在某个数,他的值和其它n-1个数的异或结果相同。那么最大值为n-1。也就是说只要可能均分,
那么就一定可以用这样的方法让最大值为n-1。这时存在的情况,那么对立面不存在,输出-1即可。本题结果为n-1,或者-1.



  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值