题目链接
http://codeforces.com/contest/779/problem/E
解题思路
感觉思路比较简单,但是模拟的过程是真的难啊
大致思路:
输入统计,为数,或者为计算式,若为计算式还需要记录左右操作数为问号还是变量。
我们优先遍历每一个二进制位,再看每个变量本位为1的个数,统计问号在本位为0时所有变量中本位为1的个数,统计问号为1时所有变量中本位为1的个数,根据最小值或最大值进行字符串拼接。
我觉得还是得看代码
AC代码
#include<bits/stdc++.h> using namespace std; const int N=5e3+10; struct node { int op,l,r;//当第i个变量为表达式时,l表示左操作数变量对应的编号,r表示右操作数变量对应的编号,op表示操作数之间的运算符,op=0表示,此变量为数而非表达式,op=1表示&,op=2表示|,op=3表示^ string s;//当第i个变量为数,而非表达式的时候,s表示二进制串(以字符串形式存储) }a[N]; map<string,int> idx;//idx[str]=i表示变量str的编号为i string var,tmp,op,s,mn="",mx=""; int t[2][N],cnt[2],n,m;//后面讲解 int main() { cin>>n>>m; for(int i=1;i<=n;i++) { cin>>var>>tmp>>a[i].s; idx[var]=i; if(isdigit(a[i].s[0])) continue;//若为数值,直接continue cin>>op>>s; if(op[0]=='A') a[i].op=1; else if(op[0]=='O') a[i].op=2; else if(op[0]=='X') a[i].op=3; a[i].l=(a[i].s=="?"?n+1:idx[a[i].s]);//如果操作数为问号,操作数为对应的编号为n+1,否则通过idx找到其对应编号 a[i].r=(s=="?"?n+1:idx[s]);//同上 // cout<<var<<' '<<tmp<<' '<<sl<<' '<<op<<' '<<sr<<endl; } //下面比较难理解了 t[0][n+1]=0,t[1][n+1]=1;//t[0][n+1]表示第n+1个变量,即问号,为0;t[1][n+1]表示第n+1个变量,即问号,为1//临时 for(int i=0;i<m;i++)//先遍历每一个二进制位 { cnt[0]=0,cnt[1]=0;//统计问号的第i个二进制位为0/1时,所有变量的第i个二进制位为1的个数 for(int k=0;k<=1;k++)//问号的第i个二进制位为0或1 { for(int j=1;j<=n;j++)//遍历每一个变量 { if(a[j].op==0) t[k][j]=a[j].s[i]-'0';//若为数值,找到数值对应的第i个二进制位。 else if(a[j].op==1) t[k][j]=t[k][a[j].l] & t[k][a[j].r]; else if(a[j].op==2) t[k][j]=t[k][a[j].l] | t[k][a[j].r]; else if(a[j].op==3) t[k][j]=t[k][a[j].l] ^ t[k][a[j].r]; if(t[k][j]) cnt[k]++;//当前二进制位为1,才进行统计 } } mn+=cnt[1]>=cnt[0]?'0':'1';//稍微注意等于的情况,自己写一下就行 mx+=cnt[1]> cnt[0]?'1':'0';//同上 } cout<<mn<<endl<<mx<<endl; }