题目链接
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;
}
京公网安备 11010502036488号