CodeForces 778B Bitwise Formula 解题报告

来源:互联网 发布:长沙蓝狐网络官网 编辑:程序博客网 时间:2024/06/04 18:48

题目:http://codeforces.com/problemset/problem/778/B
题意:给出n个变量的表达式,表达式可含有变量名、长度为m的二进制数和“?”

输入样例1:
3 3
a := 101
b := 011
c := ? XOR b

输入样例2:
5 1
a := 1
bb := 0
cx := ? OR a
d := ? XOR ?

其中,所有的“?”是同一个长度为m的二进制数
现在求使得所有变量之和最小、最大的两个“?”(如果有多个相同答案,取字典序最小的一个)

数据范围:(1 ≤ n ≤ 5000; 1 ≤ m ≤ 1000) 可见 2^1000 的暴力做法是不可取的,
但题目中的三种位运算符 “AND”“OR”“XOR”都不会造成进位,因此“?”的第i位的值是不会对其他位的运算结果产生影响的。

题解:
其实这是一道 字符串处理题 拆位题
枚举每一位取‘0’或‘1’然后取最值就可以了

代码(字符串处理比较麻烦):

#include <cstdio>#include <cstring>int n,m,i,j,res1,res2;char str[1010],min[1010],max[1010];struct var {    bool *ans,*l,*r;//bool* 表示二进制数,l,r 表示运算符左边和右边的变量或二进制数,把计算结果储存在ans里    char mode,name[15];//name 变量名 mode 为运算方式'A','O','X','C'(没有运算的赋值)} v[5010];bool *init(char *s) {//处理一个变量名或二进制数,返回bool数组指针    if (*s > '1') for (int i=0;i<=n;i++) if (!strcmp(s,v[i].name)) return v[i].ans;    bool *b = new bool[m];    for (int i=0;i<m;i++) b[i] = s[i] - '0';    return b;}int calc(var *u,int t) {//对u的第t位求值,返回0或1    switch (u->mode) {        case 'A' :  return (u->ans[t] = u->l[t] && u->r[t]) ? 1 : 0;  break;        case 'O' :  return (u->ans[t] = u->l[t] || u->r[t]) ? 1 : 0;  break;        case 'X' :  return (u->ans[t] = u->l[t] ^  u->r[t]) ? 1 : 0;  break;        default : return (u->ans[t]) ? 1 : 0; break;    }}int main() {    scanf("%d%d",&n,&m);    v[0].name[0] = '?';  v[0].ans = new bool[m];//v[0]为“?”变量    for (i=1;i<=n;i++) {//读入表达式并处理到v数组        scanf("%s := %[^\n]",v[i].name,str);        char *s = str;        while (*s != 'A' && *s != 'O' && *s != 'X' && *s) s++;        v[i].mode = (*s) ? *s : 'C';        if (!*s) {v[i].ans = init(str);  continue;}        v[i].l = init(str);        v[i].r = init(strstr(s+1," ") + 1);        v[i].ans = new bool[m];    }    for (i=0;i<m;i++) {//枚举每一位在每个变量中的值,判断01        for (j=1,v[0].ans[i] = true ;j<=n;j++) res1 += calc(v+j,i);        for (j=1,v[0].ans[i] = false;j<=n;j++) res2 += calc(v+j,i);        min[i] = (res1 >= res2) ? '0' : '1';        max[i] = (res1 <= res2) ? '0' : '1';        res1 = res2 = 0;    }    puts(min);  puts(max);}
1 0
原创粉丝点击