codeforces gym 100357 K (表达式 模拟)

题目大意

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

解题分析

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

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

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

参考程序

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3 typedef pair<int,int> pii;
  4 string s;
  5 int a[100000];
  6 int level(char ch)
  7 {
  8     switch (ch)
  9     {
 10         case ‘+‘:;
 11         case ‘-‘:return 1;
 12         case ‘*‘:;
 13         case ‘/‘:return 2;
 14         case ‘^‘:return 3;
 15         default:return 4;
 16     }
 17 }
 18
 19 int r,c,tmp=0;
 20
 21 struct node{
 22     int l,mid,r,len;
 23     char ch;
 24 }w[100000];
 25
 26 pii solve(int x,int y,int heap,int op)
 27 {
 28     //cout<<s.substr(x,y-x+1)<<endl;
 29     if (heap>r) r=heap;
 30     if (op>c) c=op;
 31     while (s[x]==‘(‘ && s[y]==‘)‘)
 32     {
 33         int t=0,flag=1;
 34         for (int i=x+1;i<=y-1;i++)
 35         {
 36             if (s[i]==‘(‘) t++; else if (s[i]==‘)‘) t--;
 37             if (t<0) flag=0;
 38         }
 39         if (flag)
 40         {
 41             x++;
 42             y--;
 43         }
 44         else break;
 45     }
 46     int len=y-x+1;
 47     if (len==1)
 48     {
 49         w[++tmp]=(node){op,op,op,heap,s[x]};
 50         return pii(1,1);
 51     }
 52     for (int i=x;i<=y;i++) a[i]=0;
 53     if (s[x]==‘(‘) a[x]=1; else a[x]=0;
 54     for (int i=x+1;i<=y;i++)
 55         if (s[i]==‘(‘) a[i]=a[i-1]+1; else
 56         if (s[i]==‘)‘) a[i]=a[i-1]-1; else
 57         a[i]=a[i-1];
 58     int p=0,mx=5;
 59     for (int i=x;i<=y;i++)
 60     {
 61         if (a[i]==0)
 62             if (s[i]==‘^‘ && level(s[i])<mx || s[i]!=‘^‘ && level(s[i])<=mx )
 63             {
 64                 p=i;
 65                 mx=level(s[i]);
 66             }
 67     }
 68     pii left=solve(x,p-1,heap+1,op);
 69     int now=op+left.second+2;
 70     pii right=solve(p+1,y,heap+1,now+3);
 71     w[++tmp]=(node){op+left.first-1,op+left.second+2,now+right.first+3-1,heap,s[p]};
 72     return pii(left.second+3,left.second+5+right.second);
 73 }
 74 int cmp(const node &a,const node &b)
 75 {
 76     return a.len<b.len || a.len==b.len && a.mid<b.mid;
 77 }
 78 int main()
 79 {
 80     freopen("tree.in","r",stdin);
 81     freopen("tree.out","w",stdout);
 82     cin>>s;
 83     pii p=solve(0,s.length()-1,1,1);
 84     sort(w+1,w+tmp+1,cmp);
 85     for (int h=1;h<=w[tmp].len;h++)
 86     {
 87         int i,j;
 88         for (i=1;w[i].len!=h;i++);
 89         for (j=i;w[j+1].len==h;j++);
 90         if (h!=1)
 91         {
 92             for (int t=1;t<=w[i].mid-1;t++) printf(" ");
 93             printf("|");
 94             for (int k=i+1;k<=j;k++)
 95             {
 96                 for (int t=w[k-1].mid+1;t<=w[k].mid-1;t++) printf(" ");
 97                 printf("|");
 98             }
 99             printf("\n");
100         }
101         for (int t=1;t<=w[i].l-1;t++) printf(" ");
102         if (level(w[i].ch)!=4) printf(".");
103         for (int t=w[i].l+1;t<=w[i].mid-2;t++) printf("-");
104         if (level(w[i].ch)!=4) printf("[");
105         printf("%c",w[i].ch);
106         if (level(w[i].ch)!=4) printf("]");
107         for (int t=w[i].mid+2;t<=w[i].r-1;t++) printf("-");
108         if (level(w[i].ch)!=4) printf(".");
109         for (int k=i+1;k<=j;k++)
110         {
111             for (int t=w[k-1].r+1;t<=w[k].l-1;t++) printf(" ");
112             if (level(w[k].ch)!=4) printf(".");
113             for (int t=w[k].l+1;t<=w[k].mid-2;t++) printf("-");
114             if (level(w[k].ch)!=4) printf("[");
115             printf("%c",w[k].ch);
116             if (level(w[k].ch)!=4) printf("]");
117             for (int t=w[k].mid+2;t<=w[k].r-1;t++) printf("-");
118             if (level(w[k].ch)!=4) printf(".");
119         }
120         printf("\n");
121     }
122 }

时间: 2024-10-09 21:43:12

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

Codeforces Gym 100187K K. Perpetuum Mobile 构造

K. Perpetuum Mobile Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100187/problem/K Description The world famous scientist Innokentiy almost finished the creation of perpetuum mobile. Its main part is the energy generator whic

codeforces gym 100357 H (DP 高精度)

题目大意 有r*s张扑克牌,数字从1到 r,每种数字有s种颜色. 询问对于所有随机的d张牌,能选出c张组成顺子的概率和组成同花的概率. 解题分析 对于组成顺子的概率,令dp[i][j][k]表示一共选出了i张牌,数字从1~j,最后有k张牌是顺子.对于每个数字进行考虑,有0~s种选法.要保证连续c张牌的顺子. 对于组成同花的概率,令dp[i][j]表示一共选出了i张牌,颜色从1~j,.对于每种颜色进行考虑,有0~r种选法.要保证没有c张牌是相同颜色的. 最后用高精度来输出答案. 参考程序 1 #i

codeforces gym 100357 I (费用流)

题目大意 给出一个或与表达式,每个正变量和反变量最多出现一次,询问是否存在一种方案使得每个或式中有且仅有一个变量的值为1. 解题分析 将每个变量拆成三个点x,y,z. y表示对应的正变量,z表示对应的反变量. 由S向每个点的x部连一条流量为1的边,表示该变量的某个正变量或反变量的取值为1. 由每个点的x部向y部和z部分别连一条流量为1的边,表示每个正变量和反变量仅有一个取值为1. 若某个或式中含有某个变量,则由该变量的y部或z部向或式连一条流量为1的边.表示该变量可以使该或式的结果为1. 由每个

codeforces gym 100357 J (网络流)

题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余的物品来换取自己需要的物品. 询问主角是否能建造成功自己的建筑,并给出方案. 解题分析 超级恶心的读入,而且有一组数据的给出方式里没有逗号,和样例所示不同= = 根据py的性质很容易想到用网络流来做.将每种物品拆成x,y两份. 若主角多了a物品b件,连一条S到物品a,x部流量为b的边. 若主角少了a

codeforces gym 101164 K Cutting 字符串hash

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

【模拟】ECNA 2015 I What&#39;s on the Grille? (Codeforces GYM 100825)

题目链接: http://codeforces.com/gym/100825 题目大意: 栅栏密码.给定N(N<=10),密钥为一个N*N的矩阵,'.'代表空格可以看到,'X'代表被遮挡,还有密文字符串S,长度为N*N 每次将这个矩阵顺时针旋转90°,把矩阵中空格对应的位置按照从上到下从左到右的顺序依次填充上密文字符,求最终这个密文字符能否填满N*N的矩阵,能按顺序输出得到的答案,不能输出"invalid grille" 题目思路: [模拟] 直接模拟即可.旋转的坐标公式很好推.

Codeforces gym Hello 2015 Div1 B and Div2 D

Codeforces gym 100571 problem D Problem 给一个有向图G<V,E>和源点S,边的属性有长度L和颜色C,即E=<L,C>.进行Q次询问,每次给定一个点X,输出S到X的最短路的长度(不存在则输出 -1).但要求S到X的路径中相邻两条边颜色不一样. Limits Time Limit(ms): 1000 Memory Limit(MB): 256 |V|, |E|: [1, 10^5] X, S: [1, |V| ] L: [1, 10^9] |C|

Codeforces gym Hello 2015 Div1 E

Codeforces gym 100570 problem E (一种处理动态最长回文子串问题的方法) Problem 给一个长度为N的字符串S,字符集是'a'-'z'.进行Q次操作,操作分三种.一,修改位置X的字符为C:二,查询以P位置为中心的最长回文子串的长度,并输出:三,查询以P与P+1的中间位置为中心的最长回文子串的长度,并输出. More 第二种操作子串长度为奇数,一定存在:第三种操作子串长度为偶数,若不存在,输出 -1. Limits Time Limit(ms): 4000(1s足

Codeforces gym Hello 2015 Div1 C and Div2 E

Codeforces gym 100570 problem C Codeforces gym 100571 problem E Problem 给一个N行M列的矩阵Ma,进行Q次(Q<=10)查询,每次给定一个K,问有多少子矩阵,满足最大值max - 最小值min <=K. Limits Time Limit(ms): 8000 Memory Limit(MB): 512 N, M: [1, 400] Q: [1, 10] Ma(i, j), K: [1, 10^9] Solution (Th