按二进制位考虑,每一个位在做了那些操作之后,最后的结果是唯一的,那么从高位到低位开始贪心就好
trick:门上的数字可能大于m,所以贪心的时候不应该从m的最高位开始,而是应该从所有的数字的最高位开始
一个被我强行写长了的代码….
#include<bits/stdc++.h>
using namespace std;
#define LL long long
int biter(int x,int *s){
int len = 0;
while(x){
s[len++] = x % 2;
x /= 2;
}
return len;
}
struct Door{
string ord;
int len,v[40];
void init(){
int x;
cin>>ord>>x;
memset(v,0,sizeof(v));
len = biter(x,v);
}
};
const int maxn = 112345;
Door door[maxn];
int n;
int aftdoor(int pos,int bit){
for(int i=0;i<n;i++){
if(door[i].ord == "AND")
bit = bit & door[i].v[pos];
if(door[i].ord == "OR")
bit = bit | door[i].v[pos];
if(door[i].ord == "XOR")
bit = bit ^ door[i].v[pos];
}
return bit;
}
int num[40],ans[40];
void dfs(int pos,bool bnd){
if(pos<0)
return;
int zero = aftdoor(pos,0);
int one = aftdoor(pos,1);
int ed = bnd ? num[pos] : 1;
int choice;
if(ed == 0){
choice = 0;
ans[pos] = zero;
}
else{
if(zero >= one){
choice = 0;
ans[pos] = zero;
}
else{
choice = 1;
ans[pos] = one;
}
}
dfs(pos-1,bnd && choice==num[pos]);
}
int main(){
int m;
while(cin>>n>>m){
for(int i=0;i<n;i++){
door[i].init();
}
memset(num,0,sizeof(num));
memset(ans,0,sizeof(ans));
int len = biter(m,num);
dfs(39,true);
LL anw = 0;
for(int i=39;i>=0;i--){
anw = anw * 2 + ans[i];
}
cout<<anw<<endl;
}
return 0;
}
以及一个重新写了一遍的代码
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn = 40;
void biter(int *s,LL x){
for(int i=0;i<maxn;i++){
s[i] = x % 2;
x /= 2;
}
}
int aone[maxn],azero[maxn];
int number[maxn];
int main(){
int n,m;
while(cin>>n>>m){
LL one = 1,zero = 0;
one = (one << maxn)-1;
string ord;
LL num;
while(n--){
cin>>ord>>num;
if(ord == "AND")
one &= num,zero &= num;
if(ord == "OR")
one |= num,zero |= num;
if(ord == "XOR")
one ^= num,zero ^= num;
}
biter(aone,one);
biter(azero,zero);
biter(number,m);
bool bnd = true;
LL ans = 0;
for(int pos = maxn-1;pos>=0;pos--){
ans *= 2;
if((bnd && number[pos]==0) || (aone[pos] <= azero[pos])){
ans += azero[pos];
bnd = bnd && number[pos]==0;
}
else{
ans += aone[pos];
bnd = bnd && number[pos]==1;
}
}
cout<<ans<<endl;
}
return 0;
}