发现现在完全不会写了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 }
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 }
为什么WA了这么多次呢?
因为.......
我new节点的时候忘记把deg初始化了TAT
什么鬼啊这....唉人蠢没办法.......