当前位置: 代码迷 >> 综合 >> ACdream 1023 Xor
  详细解决方案

ACdream 1023 Xor

热度:77   发布时间:2023-12-06 03:27:27.0

题目链接:http://acdream.info/problem?pid=1023

题意:给一个集合A,一个集合B,问可否存在一个数字C,使得A中所有元素和C做异或运算得到B集合。

小编做这道题的时候真的是很幸运,在草稿本上画字典树的时候,打了几个表一下子就被小编发现规律了,在验证的时候也没想太严谨,但是运气好的出奇的一A了。

首先,小编发现 一句话,n is odd,起初没有在意这句话,可能第一次看到它也觉得没什么吧,那我们先把这句话放到一边。

先来分析,A我们可以看成{a1,a2,a3……},B我们可以看成{a1^c,a2^c,a3^c……},写到这里小编在想异或运算是否有一个性质,那就是如果a^b = c,那么a^c = b,当时小编列了很多关于0和1是否相等的式子 ,在给别人讲的时候我也是说的因为0和1始终保持一个相等的个数,因为有0^1=1,1^1=1,0^0=0这些等式,但是小编刚刚发现麻烦了……这样讲似乎还误导了一些人,因为直接就可以证明:a^c = a^(a^b) = a^a^b = b,当时小编想,可不可以用字典树贪心在A集合中找到这个每一位对应的^c在B中的值,在列字典树的时候我想了一下该从高位开始列还是从低位开始列,于是先在草稿纸上写了样例的数据A{00,01,11}->B{01,10,11},突然发现A的总异或运算值x1^B的总异或运算值x2就等于c,一开始以为是个巧合,但是马上就得到了证明,因为B的总异或运算值x2就等于a1^c^a2^c^a3^c……那么就等于x1^c^c^c^c^c……明显当c的个数是偶数的话就是0,奇数就是1,这个时候那句n is odd就有用了,所以x1^x2的结果一定等于c。

但是这个计算结果又一定是正确的吗,我们这样做是建立在有c的情况下,如果c存在一定满足,如果c不存在只是满足x1 ^ c=x2,但不满足每一位相等,就不能这样计算了,我们还得证明A的每一位^c之后和B一样,这个时候应该是队友没听懂我的思路,胡乱说可不可以加起来判断,当时听了觉得有道理……试了一下,就真的A了……(运气真的不是一般的好)。

这道题从我读题到A掉只用了不到5分钟的时间,中间各种巧合,现在写题解的时候才发现还是有很多值得思考的地方,比如异或运算的性质之类的。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 100005;
int a[maxn],b[maxn];
int main()
{int n;while(scanf("%d",&n) !=EOF){int x1 = 0,x2 = 0,tmp;int sum1 = 0,sum2 = 0;for(int i=1; i<=n; i++){scanf("%d",&a[i]);x1 ^= a[i];}for(int i=1; i<=n; i++){scanf("%d",&b[i]);x2 ^= b[i];sum2 += b[i];}x1 ^= x2;for(int i=1; i<=n; i++)sum1 += x1^a[i];if(sum1 == sum2) printf("%d\n",x1);else printf("-1\n");}
}