题目大意

将一个含有+,-,^,()的表达式按照运算顺序转换成树状的形式。

解题分析

  用递归的方式来处理表达式,首先直接去掉两边的括号(如果不止一对全部去光),然后找出不在括号内且优先级最低的符号。如果优先级相同,则如果是左结合性(+,-,*,/)则选择最右边的一个,如果是右结合性(^)则选择最最左边的一个。

  主要恶心的地方在于输出上。主要是记录一下每个点和符号的位置,在递归和返回时传递一些参数。

  ps:虽然输出比较恶心,但最终实现出来后还是感到十分地身心愉悦。

参考程序

 #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
string s;
int a[];
int level(char ch)
{
switch (ch)
{
case '+':;
case '-':return ;
case '*':;
case '/':return ;
case '^':return ;
default:return ;
}
} int r,c,tmp=; struct node{
int l,mid,r,len;
char ch;
}w[]; pii solve(int x,int y,int heap,int op)
{
//cout<<s.substr(x,y-x+1)<<endl;
if (heap>r) r=heap;
if (op>c) c=op;
while (s[x]=='(' && s[y]==')')
{
int t=,flag=;
for (int i=x+;i<=y-;i++)
{
if (s[i]=='(') t++; else if (s[i]==')') t--;
if (t<) flag=;
}
if (flag)
{
x++;
y--;
}
else break;
}
int len=y-x+;
if (len==)
{
w[++tmp]=(node){op,op,op,heap,s[x]};
return pii(,);
}
for (int i=x;i<=y;i++) a[i]=;
if (s[x]=='(') a[x]=; else a[x]=;
for (int i=x+;i<=y;i++)
if (s[i]=='(') a[i]=a[i-]+; else
if (s[i]==')') a[i]=a[i-]-; else
a[i]=a[i-];
int p=,mx=;
for (int i=x;i<=y;i++)
{
if (a[i]==)
if (s[i]=='^' && level(s[i])<mx || s[i]!='^' && level(s[i])<=mx )
{
p=i;
mx=level(s[i]);
}
}
pii left=solve(x,p-,heap+,op);
int now=op+left.second+;
pii right=solve(p+,y,heap+,now+);
w[++tmp]=(node){op+left.first-,op+left.second+,now+right.first+-,heap,s[p]};
return pii(left.second+,left.second++right.second);
}
int cmp(const node &a,const node &b)
{
return a.len<b.len || a.len==b.len && a.mid<b.mid;
}
int main()
{
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
cin>>s;
pii p=solve(,s.length()-,,);
sort(w+,w+tmp+,cmp);
for (int h=;h<=w[tmp].len;h++)
{
int i,j;
for (i=;w[i].len!=h;i++);
for (j=i;w[j+].len==h;j++);
if (h!=)
{
for (int t=;t<=w[i].mid-;t++) printf(" ");
printf("|");
for (int k=i+;k<=j;k++)
{
for (int t=w[k-].mid+;t<=w[k].mid-;t++) printf(" ");
printf("|");
}
printf("\n");
}
for (int t=;t<=w[i].l-;t++) printf(" ");
if (level(w[i].ch)!=) printf(".");
for (int t=w[i].l+;t<=w[i].mid-;t++) printf("-");
if (level(w[i].ch)!=) printf("[");
printf("%c",w[i].ch);
if (level(w[i].ch)!=) printf("]");
for (int t=w[i].mid+;t<=w[i].r-;t++) printf("-");
if (level(w[i].ch)!=) printf(".");
for (int k=i+;k<=j;k++)
{
for (int t=w[k-].r+;t<=w[k].l-;t++) printf(" ");
if (level(w[k].ch)!=) printf(".");
for (int t=w[k].l+;t<=w[k].mid-;t++) printf("-");
if (level(w[k].ch)!=) printf("[");
printf("%c",w[k].ch);
if (level(w[k].ch)!=) printf("]");
for (int t=w[k].mid+;t<=w[k].r-;t++) printf("-");
if (level(w[k].ch)!=) printf(".");
}
printf("\n");
}
}

codeforces gym 100357 K (表达式 模拟)的更多相关文章

  1. Codeforces Gym 100851 K King's Inspection ( 哈密顿回路 && 模拟 )

    题目链接 题意 : 给出 N 个点(最多 1e6 )和 M 条边 (最多 N + 20 条 )要你输出一条从 1 开始回到 1 的哈密顿回路路径,不存在则输出 " There is no r ...

  2. Codeforces Gym 100187K K. Perpetuum Mobile 构造

    K. Perpetuum Mobile Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...

  3. codeforces gym 100971 K Palindromization 思路

    题目链接:http://codeforces.com/gym/100971/problem/K K. Palindromization time limit per test 2.0 s memory ...

  4. Codeforces Gym 100523K K - Cross Spider 计算几何,判断是否n点共面

    K - Cross SpiderTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/v ...

  5. codeforces gym 100357 H (DP 高精度)

    题目大意 有r*s张扑克牌,数字从1到 r,每种数字有s种颜色. 询问对于所有随机的d张牌,能选出c张组成顺子的概率和组成同花的概率. 解题分析 对于组成顺子的概率,令dp[i][j][k]表示一共选 ...

  6. codeforces gym 100357 I (费用流)

    题目大意 给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1. 解题分析 将每个变量拆成三个点x,y,z. y表示对应的正变量,z表示对应的 ...

  7. codeforces gym 100357 J (网络流)

    题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...

  8. codeforces gym 101164 K Cutting 字符串hash

    题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #prag ...

  9. Codeforces Gym 101190M Mole Tunnels - 费用流

    题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...

随机推荐

  1. VUE中全局变量的定义和使用

    目录 VUE中全局变量的定义和使用 1.工作中遇到的两类问题 1.1 状态值(标志) 1.2 传递字段 2.解决方法 2.1 VUEX 2.2 使用全局变量法管理状态与字段值 3.具体实现 3.1创建 ...

  2. mysql插入二千万的测试数据进行测试,int和datetime比较

    时间存储用int和datetime哪个字段更合适,建立下面的两个表 测试环境是内存2个G,一核的虚拟机 CREATE TABLE `test_inttime` ( `id` int(11) NOT N ...

  3. [IOI1998]Polygon

    很早就看到这题了...但因为有个IOI标志,拖到现在才做 由于是以前在书上看到的,就没有想过其他算法,直接区间DP了... 方程式也挺好想的 跟我们平时做数学题求几个数乘积最大差不多 最大的*最大的 ...

  4. ACM_下一个排列

    The Next Permutation Time Limit: 2000/1000ms (Java/Others) Problem Description: For this problem, yo ...

  5. EntityFramework(转自wiki)

    维基百科 Entity Framework (又称ADO.NET Entity Framework) 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping)解决方案,早期 ...

  6. 395 Longest Substring with At Least K Repeating Characters 至少有K个重复字符的最长子串

    找到给定字符串(由小写字符组成)中的最长子串 T , 要求 T 中的每一字符出现次数都不少于 k .输出 T 的长度.示例 1:输入:s = "aaabb", k = 3输出:3最 ...

  7. 设置打印机共享,适用Win7、Vista、xp,不用密码

    此处以HP M1213nf为例,其他型号大同小异. 1.设置打印机共享: "开始"→  "控制面板"→  "设备和打印机" 2.找到&quo ...

  8. 计算机二级C语言冲刺笔记。

    2018-03-0618:32:26 风萧萧兮易水寒,壮士一去...... 四级依旧没过,计算机二级接踵而至, default语句在switch语句中可以省略,所以B错误:switch语句中并非每个c ...

  9. Python学习日记之读取中文目录

    unicode # -*- coding:utf-8 -*- import os import shutil ins="E:\\学习资料" dir=unicode(ins,'utf ...

  10. Python中深拷贝与浅拷贝的区别

    转自:http://blog.csdn.net/u014745194/article/details/70271868 定义: 在Python中对象的赋值其实就是对象的引用.当创建一个对象,把它赋值给 ...