zoukankan      html  css  js  c++  java
  • Codeforces Problem 778B Bitwise Formula

    题目链接:http://codeforces.com/contest/779/problem/E

    题意:有n个变量都可以用m位二进制数表示,这n个数的value将以两种格式中的一种给出

    1.变量名, 空格, ":=", 空格, 一个正好m位的二进制数

    eg(m = 3):   a := 101

    2.变量名, 空格, ":=", 空格第一个变量, 空格, 位运算符(AND,OR,XOR), 空格, 第二个变量

    每一个变量都是前面被定义过的变量或者用 '?'表示

    eg:  aaa := a AND  aa

           bbb := b XOR ?

    你需要确定'?'这个m位的二进制数,并输出使n个数总和最小和最大时的'?'

    maxn = 5000

    maxm = 1000

    解法:一个稍复杂的二进制模拟题

    '?'这个二进制数的m位每一位都有2种可能

    所以与'?'有关的所有变量的二进制表示中每一位最多都有2种可能

    注意到第二种读入中可能某个变量的值与'?'有关,后面这个变量又会参与运算

    所以我们当计算第 i 个数时,需要保证前i - 1个数都已经被计算出来

    所以解题思路就是直接计算出所有变量

    然而如果读入一个算式立即用if各种判断的话,写出来会很丑很长

    我们需要考虑简化代码 (参考了rank2的代码

    注意到我们如果循环读入一个变量立刻计算其value需要O(nm)的空间

    转化为全部读入后再一位一位的处理只需要O(n)的空间

    我们可以v1和v2表示参与运算的变量的标号('?'被表示为第n+1个变量)

    并用op来记录是哪种位运算符,最后统一处理就方便了很多

    (string+map大法好

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 map <string, int> p;
     6 
     7 int n, m, c[2];
     8 
     9 int s[2][5010];
    10 
    11 struct node {
    12     int op;
    13     int v1, v2;
    14     string s;
    15 }a[5010];
    16 
    17 int main() {
    18     string s1, s2, s3, s4, s5, ansmin = "", ansmax = "";
    19     
    20     scanf("%d %d", &n, &m);
    21     for(int i = 1;i <= n;i ++) {
    22         cin >> s1 >> s2 >> a[i].s, p[s1] = i;
    23         if(a[i].s[0] == '0' || a[i].s[0] == '1') continue;
    24         if(a[i].s[0] == '?') a[i].v1 = n + 1;
    25         else a[i].v1 = p[a[i].s];
    26         
    27         cin >> s4 >> s5;
    28         switch(s4[0]) {
    29             case 'A':a[i].op = 1;break;
    30             case 'O':a[i].op = 2;break;
    31             case 'X':a[i].op = 3;break;
    32         }
    33         if(s5[0] == '?') a[i].v2 = n + 1;
    34         else a[i].v2 = p[s5];
    35     }
    36     
    37     s[0][n + 1] = 0, s[1][n + 1] = 1;
    38     for(int i = 0;i < m;i ++) {
    39         c[0] = 0, c[1] = 0;
    40         for(int k = 0;k < 2;k ++) {
    41             for(int j = 1;j <= n;j ++) {
    42                 switch(a[j].op) {
    43                     case 0:s[k][j] = a[j].s[i] - '0';break;
    44                     case 1:s[k][j] = s[k][a[j].v1] & s[k][a[j].v2];break;
    45                     case 2:s[k][j] = s[k][a[j].v1] | s[k][a[j].v2];break;
    46                     case 3:s[k][j] = s[k][a[j].v1] ^ s[k][a[j].v2];break;
    47                 }
    48                 if(s[k][j]) c[k] ++;
    49             }
    50         }
    51         ansmin += c[0] <= c[1] ? '0' : '1';
    52         ansmax += c[0] >= c[1] ? '0' : '1';
    53     }
    54     
    55     cout << ansmin << '
    ' << ansmax; 
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    项目总结1--技术
    基于MFC的Opengl实现动画
    vs2010 MFC Opengl实现
    设计模式-状态模式
    设计模式-访问者模式
    设计模式-责任链模式
    设计模式-中介者模式
    设计模式-命令模式
    设计模式-备忘录模式
    设计模式-观察者模式
  • 原文地址:https://www.cnblogs.com/ytytzzz/p/6475341.html
Copyright © 2011-2022 走看看