zoukankan      html  css  js  c++  java
  • cf-779E (拆位)

    题目

    Problem Description

    Bob recently read about bitwise operations used in computers: AND, OR and XOR. He have studied their properties and invented a new game.
    Initially, Bob chooses integer m, bit depth of the game, which means that all numbers in the game will consist of m bits. Then he asks Peter to choose some m-bit number. After that, Bob computes the values of n variables. Each variable is assigned either a constant m-bit number or result of bitwise operation. Operands of the operation may be either variables defined before, or the number, chosen by Peter. After that, Peter's score equals to the sum of all variable values.
    Bob wants to know, what number Peter needs to choose to get the minimum possible score, and what number he needs to choose to get the maximum possible score. In both cases, if there are several ways to get the same score, find the minimum number, which he can choose.

    Input

    The first line contains two integers n and m, the number of variables and bit depth, respectively (1 ≤ n ≤ 5000; 1 ≤ m ≤ 1000).
    The following n lines contain descriptions of the variables. Each line describes exactly one variable. Description has the following format: name of a new variable, space, sign ":=", space, followed by one of:
    ||
    |-|
    |Binary number of exactly m bits.|
    |The first operand, space, bitwise operation ("AND", "OR" or "XOR"), space, the second operand. Each operand is either the name of variable defined before or symbol '?', indicating the number chosen by Peter. |
    Variable names are strings consisting of lowercase Latin letters with length at most 10. All variable names are different.

    Output

    In the first line output the minimum number that should be chosen by Peter, to make the sum of all variable values minimum possible, in the second line output the minimum number that should be chosen by Peter, to make the sum of all variable values maximum possible. Both numbers should be printed as m-bit binary numbers.

    Sample

    input output
    3 3
    a := 101
    b := 011
    c := ? XOR b
    011
    100
    5 1
    a := 1
    bb := 0
    cx := ? OR a
    d := ? XOR ?
    e := d AND bb
    0
    0

    Note

    In the first sample if Peter chooses a number 011, then a = 101, b = 011, c = 000, the sum of their values is 8. If he chooses the number 100, then a = 101, b = 011, c = 111, the sum of their values is 15.

    分析

    • 题目大概意思是这样:有n个二进制下的m位数,先输入n和m,接下来n行,输入的是每个变量的名称(一个字符串),之后可有两个输入格式:若直接是一个数,那么就代表那个变量的值就是这个数,否则输入一个简单的运算式子(字符串A+运算+字符串B),其中运算只会是“OR”“XOR”以及“AND”,A.B要可能是"?"也可能是一个之前出现过的变量名。所有式子中,"?"代表的是同一个值,我们要求出"?"的两个值,分别使得所有变量的和最大或最小。要是有多个答案,输出字典序最小的。
    • 注意位数不超过 1000,所以说肯定不是用整型来记录,那么就可以考虑拆位,把每一位拆出来单独讨论。
    • 还有,题目所涉及的“与”、“或”、“异或”对每一位的数都只是会影响到那一位上,对其他位上的数没有影响,那么我们只需枚举"?"的每一位(从1到n),看看这一位取什么值(要么是1,要么是0)时,所有变量这一位上的值得和最大或最小,就可以得出答案了。
    • 我用了个map来记录每个变量的名字以及它的编号。

    程序

    #include <cstdio>
    #include <string>
    #include <iostream>
    #include <map> 
    using namespace std;
    int n,m,val[5010][1010],f[5010],ans[2][1010];
    //f[]	0:直接被赋值 1:and	2:or	3:xor 
    string _s,a[5010],b[5010];
    map <string , int> name;
    int Get(string ss){return name[ss];}
    
    int _check(int x,int y){	//"?" 的第 x 位为 y 时改位所有变量的和
    	int Sum=0,k=1,g[5010];
    	for (int i=1; i<=n; i++){
    		if (f[i]==0) Sum+=g[i]=val[i][x];
    		else{
    			int k1,k2;
    			if (a[i]=="?") k1=y; else k1=g[Get(a[i])];
    			if (b[i]=="?") k2=y; else k2=g[Get(b[i])];
    			if (f[i]==1) Sum+=g[i]=k1&k2;
    			if (f[i]==2) Sum+=g[i]=k1|k2;
    			if (f[i]==3) Sum+=g[i]=k1^k2;
    		}
    	}
    	return Sum;
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	for (int i=1; i<=n; i++){
    		cin >>_s; name[_s]=i;
    		cin >>_s >>_s;
    		if (_s[0]=='0' || _s[0]=='1') for (int j=1; j<=m; j++) val[i][j]=_s[j-1]-'0';
    		else{
    			a[i]=_s;
    			cin >>_s; if (_s=="AND") f[i]=1; else if (_s=="OR") f[i]=2; else f[i]=3;
    			cin >>_s; b[i]=_s;
    		}
    	}
    	for (int i=1; i<=m; i++){
    		int q1,q2;
    		q1=_check(i,1);
    		q2=_check(i,0);
    		if (q1<q2) ans[0][i]=1,ans[1][i]=0;
    		else if (q1>q2) ans[0][i]=0,ans[1][i]=1;
    		else ans[0][i]=ans[1][i]=0;
    	}
    	for (int p=0; p<=1; p++){
    		for (int i=1; i<=m; i++) printf("%d",ans[p][i]);
    		printf("
    ");
    	}
    }
    
  • 相关阅读:
    githubz在add ssh key报错 Key is invalid. Ensure you've copied the file correctly 解决办法
    iOS 更改状态栏颜色
    iOS 加载图片选择imageNamed 方法还是 imageWithContentsOfFile?
    iOS UIWebView加载网页、文件、HTML
    XXX is undefine,全局搜索却只得到一个结果
    接口调用报错,全局搜索却找不到?vscode vue
    elementui下拉框选择一次以后再选,多项被选中的情况
    VUE+ elementui 表单rules validator 邮箱验证、电话号码验证、身份证验证、账号验证
    JS 验证input内容框 Demo(复制可测试)
    Vscode setting.json个人设置(包含保存格式化,空格、换行,标点符号自动增删)
  • 原文地址:https://www.cnblogs.com/hehepig/p/6685738.html
Copyright © 2011-2022 走看看