UVa 1662 Brackets Removal

https://vjudge.net/problem/UVA-1662

题意:

给出一个序列,判断序列中哪些括号是可以去掉的,只可以改变符号。输出括号最少的序列。

 

思路:

感觉这道题目就是写起来繁琐了点,我的代码比较啰嗦..

先保存每对括号的左右坐标,然后对于每一对括号,我们去寻找它前面和后面的符号,如果前后有乘除号并且括号内有加减号,那么这括号肯定是不能去掉的。另外的情况下都是可以去掉括号的,当然了,如果前面是减号或者是除号,有些符号需要相应的改变。

还有要注意一点,很重要!!

就是如果有对括号是不能去掉的,那么对于括号内的符号,我们需要标记一下。这样当我们考虑在它外面的大括号时,就不去考虑它里面的情况。

  1 #include<iostream>
  2 #include<algorithm>
  3 #include<cstring>
  4 #include<cstdio>
  5 #include<sstream>
  6 #include<vector>
  7 #include<stack>
  8 #include<queue>
  9 #include<cmath>
 10 #include<map>
 11 using namespace std;
 12 typedef long long ll;
 13 typedef pair<int,int> pll;
 14 const int INF=0x3f3f3f3f3f;
 15 const int maxn=10000+5;
 16 
 17 int cnt;
 18 int len;
 19 char str[maxn];
 20 int vis[maxn];
 21 
 22 struct node
 23 {
 24     int l,r;
 25     int d;
 26     bool operator<(const node& rhs) const
 27     {
 28         return d<rhs.d ||(d==rhs.d && l<rhs.l);
 29     }
 30 }a[maxn];
 31 
 32 
 33 int left_work(int L)
 34 {
 35     if(str[L]=='+')  return 1;
 36     else if(str[L]=='-')  return 2;
 37     else if(str[L]=='*')  return 3;
 38     else if(str[L]=='/')  return 4;
 39     else return -1;
 40 }
 41 
 42 int right_work(int R)
 43 {
 44     if(str[R]=='+')  return 1;
 45     else if(str[R]=='-')  return 2;
 46     else if(str[R]=='*')  return 3;
 47     else if(str[R]=='/')  return 4;
 48     else return -1;
 49 }
 50 
 51 
 52 int main()
 53 {
 54    // freopen("brackets.in","r",stdin);
 55     //freopen("brackets.out","w",stdout);
 56     //freopen("D:\\input.txt","r",stdin);
 57     while(~scanf("%s",str+1))
 58     {
 59         cnt=0;
 60         stack<int> sp;
 61         memset(vis,0,sizeof(vis));
 62 
 63         len=strlen(str+1);
 64         for(int i=1;i<=len;i++)
 65         {
 66             if(str[i]=='(')  sp.push(i);
 67             else if(str[i]==')')
 68             {
 69                 int x=sp.top(); sp.pop();
 70                 a[cnt].l=x;
 71                 a[cnt].r=i;
 72                 a[cnt].d=i-x;
 73                 cnt++;
 74             }
 75         }
 76 
 77         sort(a,a+cnt);
 78 /*
 79         for(int i=0;i<cnt;i++)
 80             cout<<a[i].l<<" "<<a[i].r<<endl;
 81 */
 82 
 83         for(int i=0;i<cnt;i++)
 84         {
 85             bool flag=true;
 86             int L=a[i].l,R=a[i].r;
 87 
 88             int l_op=left_work(a[i].l-1);
 89             int r_op=right_work(a[i].r+1);
 90 
 91             //前后有乘除号但括号内有加减号
 92             if(l_op==3||l_op==4||r_op==3||r_op==4)
 93             {
 94                 for(int i=L+1;i<R;i++)
 95                 {
 96                     if(vis[i]==-1)  continue;
 97                     if(str[i]=='+'||str[i]=='-')  {flag=false;break;}
 98                 }
 99 
100                 //不可变
101                 if(!flag)
102                 {
103                     for(int i=L;i<=R;i++)
104                         if(vis[i]==0)  vis[i]=-1;
105                 }
106             }
107 
108             //处理前面无符号或为加号
109             if((l_op==-1||l_op==1)&&flag)
110             {
111                 vis[L]=vis[R]=1;
112             }
113 
114 
115             //处理减号
116             if(l_op==2 && flag)
117             {
118                 vis[L]=vis[R]=1;
119                 for(int i=L+1;i<R;i++)
120                 {
121                     if(str[i]=='-' && vis[i]!=-1)   str[i]='+';
122                     else if(str[i]=='+' && vis[i]!=-1)  str[i]='-';
123                 }
124             }
125 
126             //处理乘号
127             if(l_op==3 && flag)
128             {
129                 vis[L]=vis[R]=1;
130             }
131 
132             //处理除号
133             if(l_op==4 && flag)
134             {
135                 vis[L]=vis[R]=1;
136                 for(int i=L;i<=R;i++)
137                 {
138                     if(str[i]=='*' && vis[i]!=-1)  str[i]='/';
139                     else if(str[i]=='/' && vis[i]!=-1)  str[i]='*';
140                 }
141             }
142         }
143 
144         for(int i=1;i<=len;i++)
145         {
146             if(vis[i]!=1)
147                 printf("%c",str[i]);
148         }
149         printf("\n");
150     }
151     return 0;
152 }

 

转载于:https://www.cnblogs.com/zyb993963526/p/6934284.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值