HDU 5661 Claris and XOR(贪心)

来源:互联网 发布:java软件设计什么 编辑:程序博客网 时间:2024/05/21 11:36

Claris and XOR

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 874    Accepted Submission(s): 402

Problem Description

Claris loves bitwise operations very much, especially XOR, because it has many beautiful features. He gets four positive integersa,b,c,d that satisfies ab and cd. He wants to choose two integers x,y that satisfies axb and cyd, and maximize the value of x XOR y. But he doesn't know how to do it, so please tell him the maximum value of x XOR y.

Input

The first line contains an integer T(1T10,000)——The number of the test cases.
For each test case, the only line contains four integers a,b,c,d(1a,b,c,d1018). Between each two adjacent integers there is a white space separated.

Output

For each test case, the only line contains a integer that is the maximum value ofx XOR y.

Sample Input

21 2 3 45 7 13 15

Sample Output

611
Hint
In the first test case, when and only when $x=2,y=4$, the value of $x~XOR~y$ is the maximum.In the second test case, when and only when $x=5,y=14$ or $x=6,y=13$, the value of $x~XOR~y$ is the maximum.

Source

BestCoder Round #79 (div.2)



        现在发现了,一般和异或求最值有关的题目都是贪心。这题,还有16年CCPC Final的题等。

        首先,既然是贪心,我们就是得保证,在二进制下,从高到低,每一位都尽量的取1。于是,我们可以根据两个范围分情况讨论。

        对于第i位,如果两对端点的相应位都不一样,即x和y的第i位都是既可以取1也可以取0,那么后面的位就可以不用考虑了,直接全部取1即可。至于为什么,就是说如果x取了下界确定的0,那么对于后面的所有位,相当于可以不用考虑上界了,可以全部取1;而对应y取就要取上界确定的1,这样的话,对于后面所有位,不用考虑下界限制,可以全部取0;如此一来全部0和全部1配对,就是可以保证后面最大可以是全部取1。反之同理。

        然后如果x和y都是只能取0和1当中一个的话,在判断唯一取值是否相同,如果不同,那么说明这一位可以取到1,否则就只能取到0。

        最后是x和y情况不同的时候,即x和y中一个可以取0或1,另一个只能取其中一个。这是我们也是讨论处理。对于有两种选择的数字,如果选取了上界,那么后面就可以不用管下界的限制,直接把下界变为0;如果选取了上界,那么后面可以不用馆上界的限制,直接把上界变为全是1。这个具体道理的话与第一种情况类似。改变了界限之后,不要忘了把答案的这一位变为1。

        如此一位一位的确定就能够组合出最后的最大值,时间复杂度O(logN)。具体见代码::

#include<bits/stdc++.h>#define LL long longusing namespace std;int main(){    int T,tt=0;    scanf("%d",&T);    while (T--)    {        bool tag[4]; LL a[4],ans=0;        scanf("%I64d%I64d%I64d%I64d",&a[0],&a[1],&a[2],&a[3]);        for(int i=62;i>=0;i--)        {            for(int j=0;j<4;j++)                tag[j]=(1LL<<i)&a[j];//tag用来记录对应点对应位的取值情况            if ((tag[0]^tag[1])&&(tag[2]^tag[3]))            {                ans|=(1LL<<(i+1))-1; break;//第一种情况,x和y都是0和1都能取到            } else if (!(tag[0]^tag[1])&&!(tag[2]^tag[3]))//第二种情况,x和y都是取值唯一            {                if (tag[0]^tag[2]) ans|=(1LL<<i);            } else if (tag[0]^tag[1])//第三种情况,二者之一取值唯一,另外一个取值任意            {                if (tag[0]^tag[2]) a[1]=(1LL<<i)-1;                              else a[0]=0;                ans|=(1LL<<i);            } else if (tag[2]^tag[3])            {                if (tag[1]^tag[2]) a[3]=(1LL<<i)-1;                              else a[2]=0;                ans|=(1LL<<i);            }        }        printf("%I64d\n",ans);    }    return 0;}

原创粉丝点击