codeforces gym 100357 K (表达式 模拟)
题目大意

将一个含有+,-,^,()的表达式按照运算顺序转换成树状的形式。
解题分析
用递归的方式来处理表达式,首先直接去掉两边的括号(如果不止一对全部去光),然后找出不在括号内且优先级最低的符号。如果优先级相同,则如果是左结合性(+,-,*,/)则选择最右边的一个,如果是右结合性(^)则选择最最左边的一个。
主要恶心的地方在于输出上。主要是记录一下每个点和符号的位置,在递归和返回时传递一些参数。
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 (表达式 模拟)的更多相关文章
- Codeforces Gym 100851 K King's Inspection ( 哈密顿回路 && 模拟 )
题目链接 题意 : 给出 N 个点(最多 1e6 )和 M 条边 (最多 N + 20 条 )要你输出一条从 1 开始回到 1 的哈密顿回路路径,不存在则输出 " There is no r ...
- Codeforces Gym 100187K K. Perpetuum Mobile 构造
K. Perpetuum Mobile Time Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/pro ...
- codeforces gym 100971 K Palindromization 思路
题目链接:http://codeforces.com/gym/100971/problem/K K. Palindromization time limit per test 2.0 s memory ...
- 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 ...
- codeforces gym 100357 H (DP 高精度)
题目大意 有r*s张扑克牌,数字从1到 r,每种数字有s种颜色. 询问对于所有随机的d张牌,能选出c张组成顺子的概率和组成同花的概率. 解题分析 对于组成顺子的概率,令dp[i][j][k]表示一共选 ...
- codeforces gym 100357 I (费用流)
题目大意 给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1. 解题分析 将每个变量拆成三个点x,y,z. y表示对应的正变量,z表示对应的 ...
- codeforces gym 100357 J (网络流)
题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...
- codeforces gym 101164 K Cutting 字符串hash
题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #prag ...
- Codeforces Gym 101190M Mole Tunnels - 费用流
题目传送门 传送门 题目大意 $m$只鼹鼠有$n$个巢穴,$n - 1$条长度为$1$的通道将它们连通且第$i(i > 1)$个巢穴与第$\left\lfloor \frac{i}{2}\rig ...
随机推荐
- echarts-gl 3D柱状图保存为图片,打印
echarts-gl生成的立体柱状图生成图片是平面的,但是需求是3D图并且可以打印,我们的思路是先转成图片,然后再打印,代码如下: 生成3D图 <td>图表分析</td> &l ...
- EditText(7)EditText输入事件监听
EditText.addTextChangedListener(TextWatcher watcher); void initSearch(){ search = (EditText) findVie ...
- WIN2012的桌面和开始菜单跑到什么地方去了
传统开始菜单取消了,你把鼠标指针移动到左下角的边缘,会有一个小浮窗,就是开始,再点开始就能进到一个全屏的层里面,跟手机界面,那个玩意就是新一代的开始菜单,程序菜单,你在开始菜单上,鼠标右键点一下,下面 ...
- 安装linux mint 18.3 后要做的
使用u盘安装的linux mint 18.3,安装过程基本顺利 发现在安装过程中使用中文语言的话会使得下载附加软件的速度快很多 安装完成之后要做的事情有: 1.字体 默认的楷体字比较难看,在软件管理器 ...
- sqlserver如何查询一个表的主键都是哪些表的外键
select object_name(a.parent_object_id) 'tables' from sys.foreign_keys a where a.referenced_object_ ...
- java设计模式之策略模式总结
策略模式的定义:(定义截自http://www.cnblogs.com/whgk/p/6087064.html) 1.策略模式定义了算法族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立 ...
- C++标准库 vector排序
前天要做一个对C++ STL的vector容器做一个排序操作,之前一直把vector当做一个容量可自动变化的数组,是的,数组,所以打算按照对数组进行排序的方法:用快速排序或是冒泡排序等算法自己写一个排 ...
- php利用array_filter()过滤数组空值
利用array_filter过滤数组空值 <?php $array = array( 0 => '霜天部落', 1 => false, 2 => 1, 3 => null ...
- Linux下查看CPU信息、机器型号等硬件信息命令
Linux下查看CPU信息.机器型号等硬件信息命令 编写一个bash脚本: vim info.sh #!/bin/bash cat /etc/issue echo "____________ ...
- 09Java Server Pages 错误处理
Java Server Pages 错误处理 通常JSP在执行的时候,在两个阶段会发生错误.第一个是JSP网页转译成Servlet类的时候,另一个就是Servlet类处理每一个请求的时候.在第一个阶段 ...