题目链接:https://ac.nowcoder.com/acm/problem/17857
题解参考链接:https://ac.nowcoder.com/acm/contest/view-submission?submissionId=46500356
题意:
思路:枚举,用一个全0和全1的数跑一遍操作,然后按位枚举,如果当前位为0结果此位为1则此位为0,否则如果当前位为1结果此位为1时,判断当前位为1时构造的数是否小于等于m,如果为0和为1都不满足条件则此位置0
坑点:int默认为有符号数,所以第一位为符号位,数值位为31位,分别是0~30位,遍历的时候要注意,除非定义的是unsigned int 可以遍历0~31位。
反思:我的思维方式和编码风格都太暴力了,以后每做一道题都去看看最短代码和耗时耗空间少的别人的代码
扩展:c++11 中一些小众的关键字:
参考链接:https://blog.csdn.net/oyoung_2012/article/details/78718226
and 等效于 &&
and_eq 等效于 &=
or 等效于 ||
or_eq 等效于 |=
xor 等效于 ^
xor_eq 等效于 ^=
not 等效于 !
not_eq 等效于 !=
bitand 等效于 & 位运算
bitor 等效于 | 位运算
我写的又丑又长的代码
#include<iostream>
#include<string>
#define M 100005
using namespace std;
int b[M];
int num,n;
string s;
int main (){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int ans0=0,ans1=-1;
int res=0;
cin>>n>>num;
for(int i=1;i<=n;i++){
cin>>s>>b[i];
if(s[0]==‘A‘){
ans0&=b[i];
ans1&=b[i];
}
else if(s[0]==‘O‘){
ans0|=b[i];
ans1|=b[i];
}
else {
ans0^=b[i];
ans1^=b[i];
}
}
int ans=num;
for(int len=30;len>=0;len--){
res=res+(1<<len);
if(ans0&(1<<len)){
ans=(ans|(1<<len))-(1<<len);
}
else if((ans1&(1<<len))&&((ans|(1<<len))<=num)){
ans=(ans|(1<<len));
}
else {
ans=(ans|(1<<len))-(1<<len);
res=res-(1<<len);
}
}
cout<<res<<endl;
return 0;
}
参考上述题解链接后改的代码:
#include<iostream>
#include<string>
#define M 100005
using namespace std;
int b[M];
int num,n;
string s;
int main (){
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int ans0=0,ans1=-1;
int res=0;
cin>>n>>num;
for(int i=1;i<=n;i++){
cin>>s>>b[i];
if(s[0]==‘A‘){
ans0&=b[i];
ans1&=b[i];
}
else if(s[0]==‘O‘){
ans0|=b[i];
ans1|=b[i];
}
else {
ans0^=b[i];
ans1^=b[i];
}
}
int ans=num;
for(int len=30;len>=0;len--){
res=res+(1<<len);
if(ans0&(1<<len)){
ans=(ans|(1<<len))-(1<<len);
}
else if((ans1&(1<<len))&&((ans|(1<<len))<=num)){
ans=(ans|(1<<len));
}
else {
ans=(ans|(1<<len))-(1<<len);
res=res-(1<<len);
}
}
cout<<res<<endl;
return 0;
}
原文:https://www.cnblogs.com/abestxun/p/14322671.html