表达式树

发现现在完全不会写了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

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

 

原文地址:https://www.cnblogs.com/DragoonKiller/p/4553070.html