• 表达式树


    发现现在完全不会写了QAQ

    虽然考得跟HanoiTower一样少但是还是总结一下吧.....

     

    表达式的处理方法:

    前缀和后缀很简单呐....就讲中缀啦啦啦......

    首先,我们要把数字和符号分开. 如果原题只给了符号没给数字(或字母),我们需要手动加上去.

    具体的添加规则:

    如果当前符号c满足以下条件之一:

      1.c是运算符

      2.c是右括号

      3.c是表达式末尾(的空字符) ,前一个符号不是左括号

    那么在当前符号的前面插入一个变量.

    分开以后就可以开心地扫描了.......

    开两个栈. 我们把这样一个操作:

    "取变量栈顶两个元素和符号栈顶一个元素,做运算后把结果(或者代表这个结果的节点)压入变量栈",

    叫做一次运算.

    扫到数字: 直接压入变量栈.

    扫到左括号"(": 直接压入符号栈.

    扫到右括号")": 一直进行运算直到 1.符号栈碰到左括号 2.符号栈空. 如果碰到左括号记得删掉它.

    扫到运算符: 把那个运算符记为x.

      如果x是左结合的(同级运算从左到右),那么一直进行运算直到满足下列条件之一:

          1.符号栈顶的符号优先级小于x的优先级 2.碰到左括号.

      如果x是右结合的(同级运算从右到左),那么一直进行运算直到满足下列条件之一:

          1.符号栈顶的符号优先级不大于x的优先级 2.碰到左括号.

      实现的时候我们总是认为左括号的优先级为无穷小. 这样就可以正常运算了.

    运算完以后,x入符号栈.

    如何建树呢?

    考虑我们的运算操作.我们的变量栈中存好树中的节点.

    每当一个数字(变量)被压入变量栈,我们马上给它开一个节点存储它的信息.

    如果我们进行了一次运算,那么我们为运算的结果新建一个点,存好运算符的信息,

    然后把代表着左右操作数的节点分别连到左右儿子.

     

    以上是个人用3h YY出来的奇怪解法......看别人的题解好像没人用这个......

     

    PS: 多元运算符怎么做? 大概是改一下运算操作,弹出一个或两个符号,以及三个甚至更多的操作数......

      好吧我承认我不会TAT

     

     

    AC NOIP2011普及组 表达式的值

    普及组的题都要调2.5h! WA/RE了十几次! 玩毛....

    建出表达式树以后就是裸的树DP了.

    拓扑序.

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42 
     43 //==============================================================================
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 
     48 const int MOD=10007;
     49 
     50 
     51 struct value{ int x,y; value(){} value(int a,int b):x(a),y(b){} };
     52 
     53 struct node
     54 {
     55     int v;
     56     node*f,*l,*r;
     57     value t;
     58     int deg;
     59     
     60     node(){ deg=0; f=l=r=NULL; }
     61     
     62     bool isnum()
     63     { return l==NULL && r==NULL; }
     64 };
     65 int ncnt=4000;
     66 node*nt;
     67 node*newnode()
     68 {
     69     if(ncnt==4000) { ncnt=0; nt=new node[4000]; }
     70     ncnt++; return nt++;
     71 }
     72 
     73 char inp[105000];
     74 char a[205000];
     75 int n;
     76 
     77 int op[205000]; int opt=0;
     78 node*s[205000]; int st=0;
     79 
     80 void popstack(int v)
     81 {
     82     node*x=newnode();
     83     x->v=v;
     84     s[st-1]->f=s[st-2]->f=x;
     85     x->l=s[st-2];
     86     x->r=s[st-1];
     87     s[st-2]=x;
     88     st--;
     89 }
     90 
     91 int lv[256];
     92 
     93 node*Build()
     94 {
     95     for(int i=0;i<n;i++)
     96     {
     97         if(a[i]==' ')
     98         {
     99             s[st]=newnode();
    100             //v is not necessary here.
    101             st++;
    102         }
    103         else
    104         {
    105             int v=a[i];
    106             
    107             if(v=='(')
    108             {
    109                 op[opt++]='(';
    110             }
    111              else if(v==')')
    112              {
    113                 while(opt>0 && op[opt-1]!='(') 
    114                 popstack(op[--opt]);
    115                 if(opt>0 && op[opt-1]=='(') opt--;
    116             }
    117             else
    118             {
    119                 while(opt>0 && op[opt-1]!='(' && lv[op[opt-1]]>lv[v])
    120                 popstack(op[--opt]);
    121                 op[opt++]=v;
    122             }
    123         }
    124     }
    125     
    126     while(opt>0) if(op[opt-1]!='(')
    127     popstack(op[--opt]);
    128     
    129     return s[0]; //this is root
    130 }
    131 
    132 
    133 int main()
    134 {
    135     lv['(']=0;
    136     lv[')']=500;
    137     lv['+']=1;
    138     lv['*']=2;
    139     
    140     int m=getint();
    141     for(int i=0;i<m;i++)
    142     {
    143         char c=getchar();
    144         while(c!='+' && c!='*' && c!='(' && c!=')') c=getchar();
    145         inp[i]=c; 
    146     }
    147     
    148     for(int i=0;i<m;i++)
    149     {
    150         if((inp[i]=='+' || inp[i]=='*' || inp[i]==')') &&
    151                 (i==0 || inp[i-1]!=')'))
    152         {
    153             a[n++]=' ';
    154             a[n++]=inp[i];
    155         }
    156         else a[n++]=inp[i];
    157     }
    158     if(inp[m-1]!=')') a[n++]=' ';
    159     
    160     node*root=Build();
    161     
    162     queue<node*> q;
    163     queue<node*> h;
    164     q.push(root);
    165     while(!q.empty())
    166     {
    167         node*x=q.front(); q.pop();
    168         if(x!=root) x->f->deg++;
    169         if(x->isnum()) 
    170             h.push(x);
    171         else
    172             q.push(x->l),
    173             q.push(x->r);
    174     }
    175     
    176     while(!h.empty())
    177     {
    178         node*x=h.front(); h.pop();
    179         
    180         if(x->isnum())
    181             x->t=value(1,1);
    182         else
    183         {
    184             int ax=x->l->t.x;
    185             int ay=x->l->t.y;
    186             int bx=x->r->t.x;
    187             int by=x->r->t.y;
    188             
    189             if(x->v=='+')
    190             x->t=value(ax*bx%MOD,(ax*by+ay*bx+ay*by)%MOD);
    191             else
    192             x->t=value((ax*bx+ax*by+ay*bx)%MOD,ay*by%MOD);
    193         }
    194         
    195         if(x!=root)
    196         {
    197             x->f->deg--;
    198             if(x->f->deg==0) h.push(x->f);
    199         }
    200     }
    201     
    202     printf("%d
    ",root->t.x);
    203     
    204     return 0;
    205 }
    View Code

    DFS. 在VIJOS和TYVJ上均RE最后一个点 TAT

      1 #include <cstdio>
      2 #include <fstream>
      3 #include <iostream>
      4  
      5 #include <cstdlib>
      6 #include <cstring>
      7 #include <algorithm>
      8 #include <cmath>
      9  
     10 #include <queue>
     11 #include <vector>
     12 #include <map>
     13 #include <set>
     14 #include <stack>
     15 #include <list>
     16  
     17 typedef unsigned int uint;
     18 typedef long long int ll;
     19 typedef unsigned long long int ull;
     20 typedef double db;
     21  
     22 using namespace std;
     23  
     24 inline int getint()
     25 {
     26     int res=0;
     27     char c=getchar();
     28     bool mi=false;
     29     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     30     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     31     return mi ? -res : res;
     32 }
     33 inline ll getll()
     34 {
     35     ll res=0;
     36     char c=getchar();
     37     bool mi=false;
     38     while(c<'0' || c>'9') mi=(c=='-'),c=getchar();
     39     while('0'<=c && c<='9') res=res*10+c-'0',c=getchar();
     40     return mi ? -res : res;
     41 }
     42 
     43 //==============================================================================
     44 //==============================================================================
     45 //==============================================================================
     46 //==============================================================================
     47 
     48 const int MOD=10007;
     49 
     50 struct node
     51 {
     52     int v;
     53     node*f,*l,*r;
     54     
     55     node(){ f=l=r=NULL; }
     56     
     57     bool isnum()
     58     { return l==NULL && r==NULL; }
     59 };
     60 int ncnt=4000;
     61 node*nt;
     62 node*newnode()
     63 {
     64     if(ncnt==4000) { ncnt=0; nt=new node[4000]; }
     65     ncnt++; return nt++;
     66 }
     67 
     68 char inp[105000];
     69 char a[205000];
     70 int n;
     71 
     72 int op[205000]; int opt=0;
     73 node*s[205000]; int st=0;
     74 
     75 void popstack(int v)
     76 {
     77     node*x=newnode();
     78     x->v=v;
     79     s[st-1]->f=s[st-2]->f=x;
     80     x->l=s[st-2];
     81     x->r=s[st-1];
     82     s[st-2]=x;
     83     st--;
     84 }
     85 
     86 int lv[256];
     87 
     88 node*Build()
     89 {
     90     for(int i=0;i<n;i++)
     91     {
     92         if(a[i]==' ')
     93         {
     94             s[st]=newnode();
     95             //v is not necessary here.
     96             st++;
     97         }
     98         else
     99         {
    100             int v=a[i];
    101             
    102             if(v=='(')
    103             {
    104                 op[opt++]='(';
    105             }
    106              else if(v==')')
    107              {
    108                 while(opt>0 && op[opt-1]!='(') 
    109                 popstack(op[--opt]);
    110                 if(opt>0 && op[opt-1]=='(') opt--;
    111             }
    112             else
    113             {
    114                 while(opt>0 && op[opt-1]!='(' && lv[op[opt-1]]>lv[v])
    115                 popstack(op[--opt]);
    116                 op[opt++]=v;
    117             }
    118         }
    119     }
    120     
    121     while(opt>0) if(op[opt-1]!='(')
    122     popstack(op[--opt]);
    123     
    124     return s[0]; //this is root
    125 }
    126 
    127 struct value{ int x,y; value(int a,int b):x(a),y(b){} };
    128 value getres(node*x)
    129 {
    130     if(x->isnum()) return value(1,1); //first:0 ,second:1
    131     value a=getres(x->l);
    132     value b=getres(x->r);
    133     if(x->v=='+')
    134     return value(a.x*b.x%MOD,(a.x*b.y+a.y*b.x+a.y*b.y)%MOD);
    135     else
    136     return value((a.x*b.x+a.x*b.y+a.y*b.x)%MOD,a.y*b.y%MOD);
    137 }
    138 
    139 int main()
    140 {
    141     lv['(']=0;
    142     lv[')']=500;
    143     lv['+']=1;
    144     lv['*']=2;
    145     
    146     int m=getint();
    147     for(int i=0;i<m;i++)
    148     {
    149         char c=getchar();
    150         while(c!='+' && c!='*' && c!='(' && c!=')') c=getchar();
    151         inp[i]=c; 
    152     }
    153     
    154     for(int i=0;i<m;i++)
    155     {
    156         if((inp[i]=='+' || inp[i]=='*' || inp[i]==')') &&
    157                 (i==0 || inp[i-1]!=')'))
    158         {
    159             a[n++]=' ';
    160             a[n++]=inp[i];
    161         }
    162         else a[n++]=inp[i];
    163     }
    164     if(inp[m-1]!=')') a[n++]=' ';
    165     
    166     node*root=Build();
    167     
    168     printf("%d
    ",getres(root).x);
    169     
    170     
    171     return 0;
    172 }
    View Code

    为什么WA了这么多次呢?

    因为.......

    我new节点的时候忘记把deg初始化了TAT

    什么鬼啊这....唉人蠢没办法.......

     

  • 相关阅读:
    技术一定要动手做一遍才算自已的
    终于提离职了,感觉如释重负
    自我评定与学习计划
    MYSQL---INSERT...SELECT...
    MYSQL---LIMIT
    SQL---having
    MYSQL---数据定义
    CSS---Block和inline元素对比
    CSS---清除浮动
    T-SQL---分页语句
  • 原文地址:https://www.cnblogs.com/DragoonKiller/p/4553070.html
Copyright © 2020-2023  润新知