版权声明:转载于[email protected]的博客 https://blog.csdn.net/nuoyanli/article/details/88319526
题目来源: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\\fuck.in","r",stdin);
// freopen("C:\\Users\\54153\\Desktop\\fuck.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;
}