codeforces C. Creating Keys for StORages Has Become My Main Skill
目录
题目简述:
思路概况:
总代码:
https://codeforces.com/contest/2072/problem/C
题目简述:
给定两个数n和x,要求构造出一个长度为n的数组a,对该数组a有两个要求,第一是要满足,数组中的每一个元素互相进行完bitwise 'OR'(位运算中的或运算)后的值等于x,第二是要满足,MEX(a)尽可能最大;
详细解释一下MEX(a),往后也会遇到。
MEX(a):在数组a中未出现过的最小非负整数。因此MEX的范围是0~n-1,(n是数组长度)
例如:MEX{1 2 3 4}=0;MEX{0 1 3 4}=2;MEX{0 1 2 3 4 5 7}=6;
思路概况:
所以我们从0~n-1进行枚举即可保证MEX尽可能大,要求二轻松满足,接下来看要求一,我们最后要保证或完为x,换句话说就是保证或完二进制数和x相同,所以对于我们当前所枚举的i的二进制如果包含于x的二进制(包含不是官方词汇,是我的理解。例如001包含于111也包含于011也包含于001和101,不包含于100,110,010,总的来说就是i不能比x多出二进制1,但是可以少),那么这个i就是符合的就可以输出,否则输出0即可,在枚举到最后一个数时,我们需要特判一下,如果最后或完等于x了,那么直接输出,否则输出num^x(异或操作,用于补齐缺少的二进制1);
需要注意的是涉及位运算的需要加括号
例如(num^x)
因为^ 是按位异或运算符,而 << 是左移运算符,<<
运算符的优先级要比 ^
运算符高。要是把 (num^x) 外面的括号去掉,写成 (num^x)<<endl
,依据运算符优先级,<<
会先运算,也就是会先计算 x<<endl
,,而且 endl
是一个操纵符,不能用于位运算,这就会导致编译错误。
再例如(jl|i)==x
|
是按位或运算符,==
是相等比较运算符,而 ==
的优先级要高于 |,
那么依据运算符优先级,会先计算 i==x
,接着再对 jl
和 i==x
的结果进行按位或运算。
总代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
void solve()
{
int n,x,jl=0;
cin >> n >> x;
for(int i=0;i<n;i++)
{
if(i==n-1)
{
if((jl|i)==x)
{
cout << i << endl;
}
else cout << (jl^x) <<endl;
return ;
}
if((i&x)==i)
{
cout << i << ' ';
jl|=i;
}
else {
cout << 0 << ' ';
}
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int q;
cin >> q;
while (q--)
{
solve();
}
return 0;
}