Codeforces 1325D - Ehab the Xorcist
Posted stelayuri
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 1325D - Ehab the Xorcist相关的知识,希望对你有一定的参考价值。
题意:
给定两个数 u v ,求一个最短的数组
这个数组所有元素按位异或等于 u ,且和为 v
找不到输出 -1
否则输出数组的个数,再输出数组内的正整数
解题思路:
首先考虑到 -1的情况
根据二进制关系,
一个数 异或=和(自己=自己)
两个及以上数 异或<=和(二进制加法得知,等于的情况出现在多个数的二进制中 1 的位都不相同时)
所以按位异或得出的结果一定不会比被异或的数之和更大
然后对于奇偶判断,如果异或值为奇数,说明被异或的数中一定有奇数个奇数,才会导致最低位为 1
而奇数个奇数与不论多少个偶数相加,和一定也是奇数
所以异或值与和的奇偶性一定相同
排除不可能的答案后,接下来就是找答案
首先,数组内一定要是正整数
所以考虑 u=v=0 的特殊情况,直接输出一个 0 (见样例)
然后,如果 u=v≠0 ,直接输出个数为1,数值为u的特殊答案
然后我们可以发现,最直接的答案就是三个数字,其中两个数字相同,另外一个数字为异或的值 u
此时三个数就是 u (v-u)/2 (v-u)/2
因为相同的数字异或值为0,只需要让这三个数和为 v 即可
但因为要求元素最少的数组,所以要考虑能否只用两个数字就满足题意
会发现,如果 u 和 (v-u)/2 的二进制上的 1 不会在同一位同时出现
此时异或运算会等同于二进制加法运算
即 u^x^x = v
此时把 u^x 看作一个数,x看作另一个数,异或运算变成加法运算后
也就是 u+x 和 x 两个数,满足 (u+x)^x=u u+x+x=v
直接合并此时的 u+x 即可
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int main() 5 { 6 ll u,v,x,y; 7 cin>>u>>v; 8 if(u%2==v%2&&u<=v){ 9 if(u==v){ 10 if(!u) 11 cout<<"0 "; 12 else 13 cout<<"1 "<<u<<‘ ‘; 14 } 15 else{ 16 x=u; 17 y=(v-u)/2; 18 if((x&y)==0) 19 cout<<"2 "<<(x+y)<<‘ ‘<<y<<‘ ‘; 20 else 21 cout<<"3 "<<x<<‘ ‘<<y<<‘ ‘<<y<<‘ ‘; 22 } 23 } 24 else 25 cout<<"-1 "; 26 27 return 0; 28 }
以上是关于Codeforces 1325D - Ehab the Xorcist的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces1325D Ehab the Xorcist
Codeforces 1325D - Ehab the Xorcist
CodeForces 1325D - Ehab the Xorcist构造+思维