- 要把二进制数的“每一位”取反,用^((1<<n)-1),(~运算会得到一个负数,而且也没有取出前n位)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
string s[5];
int cnt[10],tot[10];//1表示可以通过改变这一位使得tot+1
void change(int x)
{
cnt[x]--;
for(int i=0;i<3;i++)
{
if(((x>>i)&1)==1)
{
tot[i]++;
}
else
{
tot[i]--;
}
}
cnt[x^7]++;
}
void restore(int x)
{
cnt[x]++;
for(int i=0;i<3;i++)
{
if(((x>>i)&1)==1)
{
tot[i]--;
}
else
{
tot[i]++;
}
}
cnt[x^7]--;
}
int calc()
{
while(1)
{
/*
cout<<tot[0]<<' '<<tot[1]<<' '<<tot[2]<<endl;
for(int i=1;i<7;i++)
{
cout<<i<<':'<<cnt[i]<<endl;
}
*/
bool f=false;
for(int i=1;i<7;i++)
{
if(cnt[i]>0)
{
int tmp=min(min(tot[0],tot[1]),tot[2]),s=tot[0]+tot[1]+tot[2];
change(i);
if(min(min(tot[0],tot[1]),tot[2])>tmp||min(min(tot[0],tot[1]),tot[2])==tmp&&tot[0]+tot[1]+tot[2]>s)
{
f=true;
break;
}
restore(i);
}
}
if(f==false)
{
for(int i=1;i<7;i++)
{
if(cnt[i]>0)
{
for(int j=i+1;j<7;j++)
{
if(cnt[j]>0)
{
int tmp=min(min(tot[0],tot[1]),tot[2]),s=tot[0]+tot[1]+tot[2];
change(i);change(j);
if(min(min(tot[0],tot[1]),tot[2])>tmp||min(min(tot[0],tot[1]),tot[2])==tmp&&tot[0]+tot[1]+tot[2]>s)
{
f=true;
break;
}
restore(i);restore(j);
}
}
if(f==true)
{
break;
}
}
}
if(f==false)
{
break;
}
}
}
return min(min(tot[0],tot[1]),tot[2]);
}
int main()
{
// freopen("1012.in","r",stdin);
// freopen("1012.out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin>>T;
while(T--)
{
int n,ans=0;
cin>>n;
cin>>s[0]>>s[1]>>s[2];
tot[0]=tot[1]=tot[2]=0;
for(int i=1;i<7;i++)
{
cnt[i]=0;
}
for(int i=0;i<n;i++)
{
if(s[0][i]==s[1][i]&&s[1][i]==s[2][i])
{
ans++;
}
else
{
cnt[(s[2][i]-'0')*4+(s[1][i]-'0')*2+s[0][i]-'0']++;
for(int j=0;j<3;j++)
{
tot[j]+=(s[j][i]=='0');
}
}
}
cout<<ans+calc()<<endl;
}
return 0;
}