题目来源:http://acm.nyist.cf/problem/1578

题目描述:

有两个正整数n,k(k <= n <= 10000),1到n中至多任取k个数,求这些数异或能得到的最大值  

输入描述:

第一行一个整数t,表示t组输入,t <= 1000

接下来t行,每行两个整数用空格分隔,表示n,k。

输出描述:

每组数据输出一个整数占一行,表示异或能得到的最大值

样例输入:

复制

1
4 1

样例输出:

4

提示:

 

来源:

上传者:ToRe

思路:对于k==1时不能异或只能取最大的自己,对于k>1一定存在一个数小于n并能使得n与其或能将n二进制位表述的0都变为1

(k >= 2,只需选n和n的反码,反码必定小于n。答案就是n的二进制位全变为1)

参考代码;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<cmath>
#include<queue>
const double pi = acos(-1);
#define N 10005
using namespace std;
int main()
{
    int n,k,t;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        if(k == 1)
        {
            cout<<n<<endl;
            continue;
        }
        else
        {
            int i=1,sum=0;
            while(1)
            {
                if(i >= n)
                    break;
                i<<=1;
                i++;
            }
            cout<<i<<endl;
        }
    }
    return 0;
}

 学长代码:

//Orz
#include<stdio.h>
#define ll long long
int main(){
//    freopen("C:\\Users\\54153\\Desktop\\***.in","r",stdin);
//   freopen("C:\\Users\\54153\\Desktop\\***.out","w",stdout);
    ll t;
    for(scanf("%lld",&t); t; --t)
    {
        ll n,m,ans=1;
        scanf("%lld%lld",&n,&m);
        if(m==1)printf("%lld\n",n);
        else {
            while(ans<<=1,n>>=1);
            printf("%lld\n",ans-1);
        }
    }
    return 0;
}