codeforces gym 100357 K (表达式 模拟)

Posted rpSebastian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
View Code

 

以上是关于codeforces gym 100357 K (表达式 模拟)的主要内容,如果未能解决你的问题,请参考以下文章

codeforces gym 100357 J (网络流)

codeforces gym 100357 I (费用流)

codeforces gym 100548f

codeforces gym 101164 K Cutting 字符串hash

Codeforces Gym101234G Dreamoon and NightMarket(优先队列,子集和第k大)

codeforces gym 102268 300iq round