题目就是要求把多余的括号序列删了,一直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 + 20; int op[maxn], del[maxn], DFN; char str[maxn]; int lenstr; void work() { lenstr = strlen(str + 1); stack<int> st; while (!st.empty()) st.pop(); DFN++; for (int i = 1; i <= lenstr; ++i) { if (str[i] == '(') st.push(i); else if (str[i] == ')') { int id = st.top(); st.pop(); op[id] = i; } } str[0] = str[lenstr + 1] = '+'; for (int i = 1; i <= lenstr; ++i) { if (str[i] != '(') continue; char pre, toNext; int id = i - 1; while (id >= 1 && del[id] == DFN) --id; if (str[id] == '+' || str[id] == '(') pre = '+'; else pre = '*'; id = op[i] + 1; 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 + 1; j <= en - 1; ++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 = 1; i <= lenstr; ++i) { if (del[i] == DFN) continue; printf("%c", str[i]); } printf(" "); } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif while (scanf("%s", str + 1) != EOF) work(); return 0; }
((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)