第一天,记下异或题
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
然后问题就来了,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 )
对于每组数据,第一行是一个正整数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.