计算表达式。

只有3种运算符:*,+,- ,

*优先级高于后两者,后两者优先级相同。

有两种符号:{},()。

利用递归和堆栈即可解决。

首先遇到左括号开始入栈直到遇到右括号,遇到右括号时对括号内的数进行计算。

考虑到*优先级较高,因此遇到*直接对其左右集合进行运算。

最后得到不含括号和*的表达式,从左往右计算即可。

http://poj.org/problem?id=2269

 #include <cstdio>
#include <cstring>
#include <algorithm>
const int maxn = ;
const int maxc = ;
char buf[maxn];
int stack[maxn][maxc];
char op[maxn];
int p, k;
int vis[maxc]; void caculate(){
//meeting eol or right paren RETURN
if(buf[p] == '\0' || buf[p] == ')') return;
if(buf[p] == '('){
int k1 = k;
++p, caculate();
//guarantee that all contents in the paren computed
//figure out the current result
for(int i = k1 + ; i < k; i++){
memset(vis, , sizeof vis);
int o = op[i] == '+' ? : -;
for(int j = ; j <= stack[k1][]; j++) ++vis[stack[k1][j]];
for(int j = ; j <= stack[i][]; j++) vis[stack[i][j]] += o;
stack[k1][] = ;
for(int j = ; j < ; j++) if(vis[j] > ) stack[k1][++stack[k1][]] = j;
}
k = k1 + ;
++p, caculate();
}
else if(buf[p] == '{'){
++p;
stack[k][] = ;
for(int i = p; buf[i] != '}'; i++, ++p) stack[k][++stack[k][]] = buf[i] - 'A';
k++;
p++;
caculate();
}else if(buf[p] == '*'){
if(buf[p + ] == '(') ++p, caculate();
else if(buf[p + ] == '{'){
++p;
stack[k][] = ;
for(int i = p; buf[i] != '}'; i++, ++p) stack[k][++stack[k][]] = buf[i] - 'A';
k++;
++p;
}
//caculate stack[k - 2] * stack[k - 1] to update stack[k - 2]
memset(vis, , sizeof vis);
for(int i = ; i <= stack[k - ][]; i++) ++vis[stack[k - ][i]];
for(int i = ; i <= stack[k - ][]; i++) ++vis[stack[k - ][i]];
stack[k - ][] = ;
for(int i = ; i < ; i++) if(vis[i] == ) stack[k - ][++stack[k - ][]] = i;
--k;
caculate();
}else{
op[k] = buf[p];
++p;
caculate();
}
} void solve(){
k = p = ;
memset(vis, , sizeof );
caculate();
for(int i = ; i < k; i++){
memset(vis, , sizeof vis);
int o = op[i] == '+' ? : -;
for(int j = ; j <= stack[i - ][]; j++) ++vis[stack[i - ][j]];
for(int j = ; j <= stack[i][]; j++) vis[stack[i][j]] += o;
stack[i][] = ;
for(int j = ; j < ; j++) if(vis[j] > ) stack[i][++stack[i][]] = j;
}
putchar('{');
for(int i = ; i <= stack[k - ][]; i++) putchar(stack[k - ][i] + 'A');
putchar('}');
putchar('\n');
} int main(){
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_Judge
while(gets(buf) && buf[] != '\0') solve();
return ;
}

poj2269 Friends的更多相关文章

随机推荐

  1. IntelliJ IDEA 常用设置讲解1

    IntelliJ IDEA 有很多人性化的设置我们必须单独拿出来讲解,也因为这些人性化的设置让我们这些 IntelliJ IDEA 死忠粉更加死心塌地使用它和分享它. 常用设置 IntelliJ ID ...

  2. String类型方法

    String类型 //1.返回长度 length var a="lynn_hello"; console.log(a.length); //2.相加 concat() 返回一个新的 ...

  3. sublime text 快速补全

    sublime text 快速补全 关于补全,其实有很多,记录一些常用的在这里,忘记了可以查找 nav>ul>li    <nav>          <ul>  ...

  4. Lintcode: Interval Minimum Number

    Given an integer array (index from 0 to n-1, where n is the size of this array), and an query list. ...

  5. HDU 4899 Hero meet devil(状压DP)(2014 Multi-University Training Contest 4)

    Problem Description There is an old country and the king fell in love with a devil. The devil always ...

  6. URAL 1001 Reverse Root(水题?)

    The problem is so easy, that the authors were lazy to write a statement for it! Input The input stre ...

  7. Linux centOS7 下安装mysql5.7.10

    1:下载二进制安装包 http://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.10-linux-glibc2.5-x86_64.tar.gz 2:解压到 ...

  8. 解析xml文件

    package com.ss1.xml; import java.io.File; import java.io.FileOutputStream; import java.io.IOExceptio ...

  9. 夺命雷公狗ThinkPHP项目之----企业网站12之文章添加的实现

    我们现在就开始写文章添加了,居然是添加当然布列外,我们还是要先讲模版搞定再说被: <!doctype html> <html> <head> <meta ch ...

  10. 一段OpenGL的简单代码

    这是基于OpenGL的代码,把它放进draw中即可.渲染出来的效果还不错 #define PI 3.14159 #define N 100 void test::Draw() { glClearCol ...