题意
告诉你 ,以及 元素符和括号搭配,组成想要的八位二进制串。
题解
第一次见到用
作为数组进行转移的,涨知识。
考虑优先级。
对于一个运算符,两个数都应该大于其优先级。
所以我们设立三个数组,分别代表最低优先级即
,中等
,最高
和括号。
也可以。
数组表达的意思就是,最后一次运算是以什么结尾的。
因为只有在低优先级进行高优先运算符运算的时候才需要加括号,所以
可以和括号看成一个。
转移的时候,因为不确定顺序,所以我们进行多次转移,知道无法进行有效转移为止。
网上写了简洁版的,就是转移的过程中不断取最小。
我写了比较暴力的转移,就是单纯分三种情况,暴力转移。
显然最低优先级的可以被高优先级的随意分配,所以是
种转移。
中等的是
种。
高等的自己转自己
种。
低级的加括号是
种
因为要求长度最小之后保证字典序最小,所以不能直接进行字符串比较。
#include<bits/stdc++.h>
#define FOR(i,l,r) for(int i=l;i<=r;i++)
#define sf(x) scanf("%d",&x)
typedef long long ll;
using namespace std;
const ll mod = 998244353;
const int maxn = 2e5+500;
int n;
string E[256],T[256],F[256];//|| & !
bool flag=true;
void update(string &A,string B){
if(A=="")A=B,flag=1;
else{
if(A.size()>B.size())A=B,flag=1;
else if(A.size()==B.size()&&A>B)A=B,flag=1;
}
}
void slove(){
int x=0,y=0,z=0;
for(int i=0;i<8;i++)if(i/4)x|=1<<i;F[x]="x";
for(int i=0;i<8;i++)if((i/2)%2)y|=1<<i;F[y]="y";
for(int i=0;i<8;i++)if(i%2)z|=1<<i;F[z]="z";
while(flag){
flag=0;
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
if(E[i].size()&&E[j].size())update(E[i|j],E[i]+'|'+E[j]);
if(E[i].size()&&T[j].size())update(E[i|j],E[i]+'|'+T[j]);
if(T[i].size()&&E[j].size())update(E[i|j],T[i]+'|'+E[j]);
if(E[i].size()&&F[j].size())update(E[i|j],E[i]+'|'+F[j]);
if(F[i].size()&&E[j].size())update(E[i|j],F[i]+'|'+E[j]);
if(T[i].size()&&T[j].size())update(E[i|j],T[i]+'|'+T[j]);
if(F[i].size()&&T[j].size())update(E[i|j],F[i]+'|'+T[j]);
if(T[i].size()&&F[j].size())update(E[i|j],T[i]+'|'+F[j]);
if(F[i].size()&&F[j].size())update(E[i|j],F[i]+'|'+F[j]);
}
}
// cout<<E[248]<<"->"<<F[248]<<"->"<<T[248]<<endl;
for(int i=0;i<256;i++){
for(int j=0;j<256;j++){
if(T[i].size()&&T[j].size())update(T[i&j],T[i]+'&'+T[j]);
if(F[i].size()&&T[j].size())update(T[i&j],F[i]+'&'+T[j]);
if(T[i].size()&&F[j].size())update(T[i&j],T[i]+'&'+F[j]);
if(F[i].size()&&F[j].size())update(T[i&j],F[i]+'&'+F[j]);
}
}
//cout<<E[248]<<"->"<<F[248]<<"->"<<T[248]<<endl;
for(int i=0;i<256;i++)if(E[i]!="")update(F[i],'('+E[i]+')');//变为最高优先级
for(int i=0;i<256;i++)if(T[i]!="")update(F[i],'('+T[i]+')');//变为最高优先级
for(int i=0;i<256;i++)if(F[i]!="")update(F[i^255],'!'+F[i]);//运算的字符串的优先级必须大于等于运算符
//for(int i=0;i<256;i++)cout<<i<<" "<<E[i]<<" "<<T[i]<<" "<<F[i]<<endl;
//puts("?");
if(!flag)break;
}
}
int main(){
slove();
cin>>n;
FOR(i,1,n){
string st;cin>>st;
int now=0;
for(int j=0;j<8;j++){
if(st[j]=='1')now|=1<<j;
}
string str;
//cout<<now<<endl;
update(str,E[now]);
update(str,F[now]);
update(str,T[now]);
cout<<str<<endl;
}
}