位运算,枚举。
按按分开计算,枚举$?$是$0$还是$1$,分别计算出$sum$,然后就可以知道该位需要填$1$还是$0$了。
#include<map> #include<set> #include<ctime> #include<cmath> #include<queue> #include<string> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<functional> using namespace std; int n,m; char s[5100][5100]; map<string,int>z; char t[5100]; int ans1[5100],ans2[5100]; int q[5100]; struct X { int op; int x1,x2; }p[5100]; int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%s",t); z[t]=i; scanf("%s",t); scanf("%s",t); if(t[0]=='0'||t[0]=='1') { p[i].op=1; strcpy(s[i],t); } else { if(t[0]=='?') p[i].x1=-1; else p[i].x1 = z[t]; scanf("%s",t); if(t[0]=='O') p[i].op=2; if(t[0]=='X') p[i].op=3; if(t[0]=='A') p[i].op=4; scanf("%s",t); if(t[0]=='?') p[i].x2=-1; else p[i].x2 = z[t]; } } for(int j=0;j<m;j++) { int sum[2]; sum[0]=sum[1]=0; for(int tx=0;tx<=1;tx++) { for(int i=1;i<=n;i++) { if(p[i].op==1) q[i] = s[i][j]-'0'; else { int x1 = p[i].x1, x2 = p[i].x2; if(x1==-1) x1 = tx; else x1 = q[x1]; if(x2==-1) x2 = tx; else x2 = q[x2]; if(p[i].op==2) q[i] = (x1|x2); else if(p[i].op==3) q[i] = (x1^x2); else if(p[i].op==4) q[i] = (x1&x2); } } for(int i=1;i<=n;i++) sum[tx]+=q[i]; } if(sum[0]==sum[1]) ans1[j]=ans2[j]=0; else if(sum[0]<sum[1]) ans1[j]=0,ans2[j]=1; else ans1[j]=1,ans2[j]=0; } for(int i=0;i<m;i++) printf("%d",ans1[i]); printf(" "); for(int i=0;i<m;i++) printf("%d",ans2[i]); printf(" "); return 0; }