zoukankan      html  css  js  c++  java
  • 【NOIP2011普及组T4】表达式的值-模拟+栈

    测试地址:表达式的值

    做法:一般求表达式值的问题都用栈来解决,而这一题栈中的每一个元素要存两个数,可以用pair来存储,first表示一段中结果为0的情况数,second表示一段中结果为1的情况数。设定一个函数f(l,r)表示[l,r]这一段所得的结果情况数(返回值形式为上述的pair),不难想到处理方法:如果l>r,返回(1,1)。由于'+'运算符优先级最低,所以一旦找到括号外的'+'运算符,它一定是最后计算的,记下位置为i。如果找不到括号外的'+'运算符,则找括号外的'*'运算符,因为'*'运算符的优先级仅高于'+'运算符,找到后记下位置为i。如果还找不到,则说明整个式子就由括号包括起来的,则返回f(l+1,r-1)(即把括号剥去计算里面的值)。对于上面记下的i,可以将剩下的字符分成两段:[l,i-1]和[i+1,r],递归求出f(l,i-1)和f(i+1,r),然后根据运算符的类型处理,即可算出f(l,r)。为了节省时间,我们可以在开始先扫一遍找出所有相对应的括号的位置,这样在寻找运算符时,如果遇到括号的一部分,就可以直接跳过括号内的全部内容,因为这里面肯定没有我们要找的东西。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #define mod 10007
    using namespace std;
    typedef pair<int,int> pa;
    char s[100010];
    int l,p[100010];
    stack<int> a;
    
    pa calc(pa a,pa b,char c)
    {
      pa so;
      if (c=='+')
      {
        so.first=(a.first*b.first)%mod;
    	so.second=((a.first*b.second)%mod+(a.second*b.first)%mod+(a.second*b.second)%mod)%mod;
      }
      else
      {
        so.first=((a.first*b.first)%mod+(a.second*b.first)%mod+(a.first*b.second)%mod)%mod;
    	so.second=(a.second*b.second)%mod;
      }
      return so;
    }
    
    pa f(int l,int r)
    {
      int i;
      if (l>r) return make_pair(1,1);
      for(i=r;i>=l;i--)
      {
        if (s[i]==')') i=p[i];
    	if (s[i]=='+') break;
      }
      if (i<l)
      {
        for(i=r;i>=l;i--)
        {
    	  if (s[i]==')') i=p[i];
    	  if (s[i]=='*') break;
    	}
      }
      else
      {
        pa x,y;
    	x=f(l,i-1);y=f(i+1,r);
    	return calc(x,y,'+');
      }
      if (i<l) return f(l+1,r-1);
      else
      {
        pa x,y;
    	x=f(l,i-1);y=f(i+1,r);
    	return calc(x,y,'*');
      }
    }
    
    int main()
    {
      scanf("%d",&l);
      scanf("%s",s);
      
      for(int i=l-1;i>=0;i--)
      {
        if (s[i]==')') a.push(i);
    	if (s[i]=='(')
    	{
    	  p[a.top()]=i;
    	  a.pop();
    	}
      }
      
      printf("%d",f(0,l-1).first%10007);
      
      return 0;
    }
    


  • 相关阅读:
    (十四)配置的热更新
    (十三)在ASP.NET CORE中使用Options
    (十二)Bind读取配置到C#实例
    【转载】ViewState的用法
    【转载】Web Service和WCF的到底有什么区别
    【转载】小小的公共库,大大的耦合,你痛过吗?
    【转载】ASP.NET应用程序与页面生命周期
    【转载】分布式数据库架构--分库、分表、排序、分页、分组、实现
    【转载】ASP和ASP.NET根本区别
    【转载】聊一聊C#的Equals()和GetHashCode()方法
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793886.html
Copyright © 2011-2022 走看看