2018蓝桥杯复现4

题目

辣个神秘的男人手上有n件装备任你选择,威力分别是从1到n。然鹅可怜的你囊中羞涩,你最多只能带走其中的k件装备。你的目标是使这些装备威力值的异或和(设装备的威力值分别为a1,a2,…ak,则他们的异或和a = a1⊕a2⊕…⊕an)最大。请问最大可以是多少。

输入格式:

装备个数n和以及你最多可以带走装备的个数k(1 <= k <= n <= 10^18)

输出格式:

装备威力值的最大异或和

输入样例1:

4 3

输出样例1:

7

输入样例2:

6 6

输出样例2:

7

代码


#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long int

ll pow(ll a,ll b)
{
    ll ans=1;
    for(ll i=0;i<b;i++)
        ans*=a;
    return ans;
}
int main()
{
    ll n,k;
    cin>>n>>k;
    if(k==1)
    {
        cout<<n<<endl;
        return 0;
    }
    int num=0;
    while(n)
    {
        if(n%2)
            n=(n-1)/2;
        else
            n=n/2;
        num++;
    }
    ll ans=0;
    for(int i=0;i<num;i++)
        ans+=pow(2,i);
    cout<<ans<<endl;
    return 0;
}

分析

  1. 关键在于理解这个异或和是啥意思,就是先把十进制的数化为二进制,然后对应位相同为1相异为0,如3异或2,即11+10=01,结果再转化为十进制,即为1 。
  2. 第二点就是题目说的是至少取k件也就是说,只要能凑到最大值,取1件也行,比如当k=1时,输出1其实就是n 。
  3. 当k>1时,会发现n的二进制位一定能再1~n-1中找到一个数的二进制形式与其进行异或和使得n的二进制位为0的变为1,也就是说,n的二进制位有m位数则答案是1+2+…+2的m-1次方
发布了21 篇原创文章 · 获赞 4 · 访问量 794

猜你喜欢

转载自blog.csdn.net/u011025050/article/details/103254118