欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

程序员文章站 2022-03-05 14:50:03
...

题目链接:https://vjudge.net/contest/246949#problem/F

先参考大佬的博客:

https://blog.csdn.net/idealism_xxm/article/details/51112303

通过这道题发现学会用位运算真的可以让程序简便很多。比如:

都是让接下来的所有位数全部变为1

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

和:

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

差距就明显了。。。

 

至于这题的细节我说明一下:

(1)

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

解释:

本来y的这一位可以取0/1的,比如0010 / 1100,但是现在这里强制取了1,所以下界最小值变成了1000,所有原本这里取0的值全部舍去,原本上界为1111,现在同样可以取到1111,所以上界不用改。同理,如果这一位强制取0,则左右原本这里是1的所有数全部舍去,即最大值变为了0111,但是现在下界不用变,因为原本最小值是0000,现在照样可以取到0000。

(2)

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

比如第i位x和y都可以取0/1,这里假如x取1,y取0,所以10000<=x<=11111 , 00000<=y<=011111 , 所以i-1位一直向右到第0位都可以取到0/1(无论x/y都是如此)

 

(3)

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

 

 

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

 

至于高端玩家的

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

这种写法老百姓还是不要轻易模仿,还是像我这样的稳如老狗的比较安全:

【NWPU2018 练着玩】入门班day1 枚举贪心[Cloned] F - Claris and XOR (HDU-5661 Claris and XOR )

 

代码:

//F - Claris and XOR
#include<stdio.h>
#include<string.h>
typedef long long LL;

int main()
{
    int i;
    int kase;
    LL a,b,c,d;
    LL cur;
    LL aa,bb,cc,dd;
    LL ans;

    scanf("%d",&kase);
    while(kase--)
    {
        scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
        ans=0;
        for(cur=(LL)1<<62;cur>0;cur>>=1)
        {
            aa=a&cur;//记录a在这一位的数字
            bb=b&cur;
            cc=c&cur;
            dd=d&cur;
            if(aa==bb)
            {
                if(cc==dd)
                    ans|=aa^cc;
                else//y的这一位可取0或1
                {
                    ans|=cur;
                    if(aa==0)//意思是y在这一位必须取1,贪心得到最大值
                        c&=cur;
                    else//y在这一位必须取0,需要改变上界
                        d|=cur-1;
                }
            }
            else//x在这一位可取0/1
            {
                ans|=cur;
                if(cc==dd)//y在这一位只能取一个
                {
                    ans|=cur;
                    if(cc==0)//y只能在这一位取0,则x必须取1,需要改变下界
                        a&=cur;
                    else
                        b|=cur-1;
                }
                else//x和y都是在这一位任意取一个
                {
                    //ans|=cur-1;
                    while(cur)
                    {
                        ans|=cur;
                        cur>>=1;
                    }
                    break;
                }
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

相关标签: 贪心