题目就是要求把多余的括号序列删了,一直wa
我的思路是暴力,暴力枚举每一对括号,在其括号区间,(没对括号都应该有属于自己的区间)暴力找是否能删除。
能删的条件是:这个括号的上一个运算是加法,这是不影响的,或者其是'(',就是((这样的情况,然后第一个括号不能删,那么第二个括号是可以删的。
否则,如果是乘法的话,那还需要看看这对括号里面是否存在加法,有就不行。
还要判断(a + b)(a + c)这样的情况,后面跟上一个乘法,
我被坑得是(ab)(c)这样的情况,中途没出现加号,是可以去除括号的。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
#include <stack>
const int maxn = 1e4 + ;
int op[maxn], del[maxn], DFN;
char str[maxn];
int lenstr;
void work() {
lenstr = strlen(str + );
stack<int> st;
while (!st.empty()) st.pop();
DFN++;
for (int i = ; i <= lenstr; ++i) {
if (str[i] == '(') st.push(i);
else if (str[i] == ')') {
int id = st.top();
st.pop();
op[id] = i;
}
}
str[] = str[lenstr + ] = '+';
for (int i = ; i <= lenstr; ++i) {
if (str[i] != '(') continue;
char pre, toNext;
int id = i - ;
while (id >= && del[id] == DFN) --id;
if (str[id] == '+' || str[id] == '(') pre = '+';
else pre = '*';
id = op[i] + ;
while (id <= lenstr && del[id] == DFN) ++id;
if (str[id] == '+' || str[id] == ')') toNext = '+';
else toNext = '*';
int be = i, en = op[i];
bool flag = true, flagadd = false;
for (int j = be + ; j <= en - ; ++j) {
if (str[j] == '(') {
j = op[j];
continue;
}
if (str[j] == '+') flagadd = true;
if (str[j] == '+' && pre == '*') {
flag = false;
break;
}
}
if (flag && (toNext != '*' || flagadd == false)) {
del[i] = del[op[i]] = DFN;
}
}
for (int i = ; i <= lenstr; ++i) {
if (del[i] == DFN) continue;
printf("%c", str[i]);
}
printf("\n");
} int main() {
#ifdef local
freopen("data.txt", "r", stdin);
// freopen("data.txt", "w", stdout);
#endif
while (scanf("%s", str + ) != EOF) work();
return ;
}
((x+y)+(z+1))y
(x+(y+z))
(x+(yz))
(x+y(x+t))
x+y+xt
a+(2b+c)(a+c)
a+(b+c)+(a+c)
xy((x+y))
xy((x+y)+z)
xy(y(x+y))
(a+c(d+e))((xyz))
(ab)(c)