【题解】表达式的值

题目描述

  对于1位二进制变量定义两种运算:

  

  运算的优先级是:

  1.先计算括号内的,再计算括号外的。

  2.“×”运算优先于“⊕”运算,即计算表达式时,先计算×运算,再计算⊕运算。

  例如:计算表达式A⊕B×C时,先计算B×C,其结果再与A做⊕运算。

  现给定一个未完成的表达式,例如_+(_×_),请你在横线处填入数字0或者1,请问有多少种填法可以使得表达式的值为0。

输入格式

  共2行:

  第一行为一个整数 L,表示给定的表达式中除去横线外的运算符和括号的个数。

  第二行为一个字符串包含L个字符,其中只包含“(”、“)”、“+”、“×”这4种字符,其中“(”、“)”是左右括号,“+”、“×”分别表示前面定义的运算符“⊕”和“×”。这行字符按顺序给出了给定表达式中除去变量外的运算符和括号。

输出格式

  一行,包含一个整数,即所有的方案数。注意:这个数可能会很大,请输出方案数对10007取模后的结果。

输入样例

4

+(*)

输出样例

3

数据规模

  对于20%的数据,0≤L≤10。

  对于50%的数据,0≤L≤1000。

  对于70%的数据,0≤L≤10000。

  对于100%的数据,0≤L≤100000。

  对于50%的数据输入表达式中不含括号。

题解

  题目中给出的是中缀表达式,我们可以先转后缀表达式,然后补上数字的位,在模拟运算一遍这个表达式即可。

#include <iostream>
#include <cstdio>
#include <stack>

#define MAX_LEN (100000 + 5)

using namespace std;

const int mod = 10007;
int len;
char s[MAX_LEN];
stack <char> st;
char ns[MAX_LEN + MAX_LEN];
int nlen;
stack <int> n0, n1;

int main()
{
    scanf("%d%s", &len, s + 2);
    len += 2;
    s[1] = ‘(‘;
    s[len] = ‘)‘;
    ns[++nlen] = ‘_‘;
    for(register int i = 1; i <= len; ++i)
    {
        if(s[i] == ‘(‘)
        {
            st.push(s[i]);
        }
        else if(s[i] == ‘)‘)
        {
            while(st.top() != ‘(‘)
            {
                ns[++nlen] = st.top();
                st.pop();
            }
            st.pop();
        }
        else if(s[i] == ‘+‘)
        {
            while(st.top() != ‘(‘)
            {
                ns[++nlen] = st.top();
                st.pop();
            }
            st.push(s[i]);
            ns[++nlen] = ‘_‘;
        }
        else
        {
            while(st.top() == ‘*‘)
            {
                ns[++nlen] = st.top();
                st.pop();
            }
            st.push(s[i]);
            ns[++nlen] = ‘_‘;
        }
    }
    int u0, u1, v0, v1;
    for(register int i = 1; i <= nlen; ++i)
    {
        if(ns[i] == ‘_‘)
        {
            n0.push(1);
            n1.push(1);
            continue;
        }
        u0 = n0.top();
        n0.pop();
        v0 = n0.top();
        n0.pop();
        u1 = n1.top();
        n1.pop();
        v1 = n1.top();
        n1.pop();
        if(ns[i] == ‘+‘)
        {
            n0.push((u0 * v0) % mod);
            n1.push((u0 * v1 + u1 * v0 + u1 * v1) % mod);
        }
        else
        {
            n0.push((u0 * v0 + u0 * v1 + u1 * v0) % mod);
            n1.push((u1 * v1) % mod);
        }
    }
    printf("%d", n0.top());
    return 0;
}

参考程序

原文地址:https://www.cnblogs.com/kcn999/p/11189368.html

时间: 2024-10-29 03:25:26

【题解】表达式的值的相关文章

NOIP2011pj表达式的值[树形DP 笛卡尔树]

题目描述 对于1 位二进制变量定义两种运算: 运算的优先级是: 先计算括号内的,再计算括号外的. “× ”运算优先于“⊕”运算,即计算表达式时,先计算× 运算,再计算⊕运算.例如:计算表达式A⊕B × C时,先计算 B × C,其结果再与 A 做⊕运算. 现给定一个未完成的表达式,例如+(*_),请你在横线处填入数字0 或者1 ,请问有多少种填法可以使得表达式的值为0 . 输入输出格式 输入格式: 输入文件名为exp.in ,共 2 行. 第1 行为一个整数 L,表示给定的表达式中除去横线外的运

表达式求值(后缀表达式求值)

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数) 输入 第一行输入一个整数n,共有n组测试数据(n<10). 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束.这个表达式里只包

2013表达式求值

题目描述 Description 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. 输入描述 Input Description 输入仅有一行,为需要你计算的表达式,表达式中只包含数字.加法运算符“+”和乘法运算符“*”,且没有括号,所有参与运算的数字均为0到2^31-1之间的整数.输入数据保证这一行只有0~9.+.*这12种字符. 输出描述 Output Description 输出只有一行,包含一个整数,表示这个表达式的值.注意:当答案长度多于4位时,请只输出最后4位,前导0不

2011表达式的值

题目描述 Description 对于 1 位二进制变量定义两种运算:运算符 运算规则⊕0⊕0=00⊕1=11⊕0=11⊕1=1×0 × 0=00 × 1=01 × 0=01 × 1=1 运算的优先级是:1. 先计算括号内的,再计算括号外的.2. “×”运算优先于“⊕”运算,即计算表达式时,先计算×运算,再计算⊕运算.例如:计算表达式A⊕B × C 时,先计算B × C,其结果再与A 做⊕运算.现给定一个未完成的表达式,例如_+(_*_),请你在横线处填入数字0 或者1,请有多少种填法可以使得表

PAT 线性结构3. 求前缀表达式的值 栈的应用

题目链接: 前缀表达式求值 题解: 同后缀表达式求值思路: 遇到数值则入栈,遇到操作符则从栈中取出最上面的两个数值进行操作,再将结果入栈,最后得到的栈顶元素则为答案. 前缀表达式从后往前遍历即可. 代码: #include<iostream> #include<cstdio> #include<cstring> #include<stack> using namespace std; int op(char a) { if(a=='+'||a=='-'||a

Matrix Chain Multiplication(表达式求值用栈操作)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1082 Matrix Chain Multiplication Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1382    Accepted Submission(s): 905 Problem Description Matrix mul

LeetCode:逆波兰表达式求值【150】

LeetCode:逆波兰表达式求值[150] 题目描述 根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说,表达式总会得出有效数值且不存在除数为 0 的情况. 示例 1: 输入: ["2", "1", "+", "3", "*"] 输出: 9 解释: ((2

【数据结构】P1981 表达式求值

题目描述 给定一个只包含加法和乘法的算术表达式,请你编程计算表达式的值. 输入格式 一行,为需要你计算的表达式,表达式中只包含数字.加法运算符“++”和乘法运算符“×”,且没有括号,所有参与运算的数字均为 0 到 2^{31}之间的整数. 输入数据保证这一行只有0−9.+.×这 1212种字符. 输出格式 一个整数,表示这个表达式的值. 注意:当答案长度多于 4 位时,请只输出最后4 位,前导0不输出. 输入输出样例 输入 #1 1+1*3+4 输出 #1 8 输入 #2 1+123456789

四则运算表达式求值 OpenJ_Bailian - 4132

四则运算表达式求值 OpenJ_Bailian - 4132 题意:设计一个计算器,实现+-*/以及()的表达式运算求值. 栈的应用,这学期学数据结构,手写了栈练一下~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn=10010; //最大表达式长度 4 5 template <typename T> 6 class Stack; 7 8 template <typename T> 9