括号匹配算面积(模拟)
链接:https://www.nowcoder.com/acm/contest/111/A
来源:牛客网
作为故事主角的托米是一名老师。
一天,他正在为解析算术表达式的课程准备课件。 在课程的第一部分,他只想专注于解析括号。 他为他的学生发明了一个有趣的正确括号序列的几何表示,如下图所示:
几何表示的定义:
1.
2.对于一个括号序列A,"(A)"的表示是由一个比g(A)宽2个单位高1个单位的矩形包围g(A),它的高度为A+1;
3.对于两个括号序列A和B,A+B的几何表示形式为把g(B)放置在g(A)右边的一个单位,且高度为A和B的高度的较大值。
其中+指的是字符串的连接符。
对于一个括号序列A,我们定义g(A)是A的几何表示形式,则
"()"的表示是一个1*1的方块,高度为1;
3.对于两个括号序列A和B,A+B的几何表示形式为把g(B)放置在g(A)右边的一个单位,且高度为A和B的高度的较大值。
其中+指的是字符串的连接符。
在完成课件后,托米老师开始玩他做好的图片。 他将图像的有限区域交替地涂成黑色和白色,使最外面的区域全部涂成黑色。 对于上面的例子,这个着色如下所示:
输入描述:
输入的第一行包含一个整数T,表示指定测试用例的数量。
每个测试用例前面都有一个空白行。
每个测试用例由一个合法括号序列组成。 每行只包含字符'('和')'。
输出描述:
对于每个测试用例,输出一行包含一个整数,表示相应几何表示的黑色部分的面积。
备注:
1≤T≤10
一个合法括号序列长度≤4 x 105
思路分析:计算一个完整的括号序列,当遇到奇数的矩形时面积进行加,偶数则减。在高度的地方要用一个栈去维护一下即可
代码示例:
#define ll long long const ll maxn = 4e5+5; char s[maxn]; ll f[maxn]; ll ans = 0; struct node { ll p, l; node (ll _p=0, ll _l=0):p(_p), l(_l){} }; stack<node>sta; void fun(ll p1, ll p2){ ll num = 0; for(ll i = p1; i <= p2; i++){ if (s[i] == '(') { num++; sta.push(node(i, 1)); } else { node v = sta.top(); sta.pop(); if (num%2 == 0) ans -= v.l*(i-v.p); else ans += v.l*(i-v.p); if (!sta.empty()){ node q = sta.top(); sta.pop(); q.l = max(q.l, v.l+1); sta.push(q); } num--; } } } int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); ll t; cin >> t; while(t--){ scanf("%s", s+1); ll len = strlen(s+1); ll cnt = 0; ans = 0; for(ll i = 1; i <= len; i++){ if (s[i] == '(') cnt++; else cnt--; f[i] = cnt; } ll p = 1; for(ll i = 1; i <= len; i++){ if (f[i] == 0){ fun(p, i); //prllf("+++ %lld %lld\n", p, i); p = i+1; } } printf("%lld\n", ans); } return 0; }
东北日出西边雨 道是无情却有情