码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces 1325D - Ehab the Xorcist

时间:2020-03-15 10:09:30      阅读:52      评论:0      收藏:0      [点我收藏+]

标签:amp   main   另一个   要求   接下来   style   its   判断   相加   

题意:

给定两个数 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\n";
12             else
13                 cout<<"1\n"<<u<<\n;
14         }
15         else{
16             x=u;
17             y=(v-u)/2;
18             if((x&y)==0)
19                 cout<<"2\n"<<(x+y)<< <<y<<\n;
20             else
21                 cout<<"3\n"<<x<< <<y<< <<y<<\n;
22         }
23     }
24     else
25         cout<<"-1\n";
26     
27     return 0;
28 }

 

Codeforces 1325D - Ehab the Xorcist

标签:amp   main   另一个   要求   接下来   style   its   判断   相加   

原文地址:https://www.cnblogs.com/stelayuri/p/12495726.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!