括號匹配算面積(模擬)
阿新 • • 發佈:2018-06-02
cli ref class src 米老師 課程 freopen std 描述
幾何表示的定義: 1. 對於一個括號序列A,我們定義g(A)是A的幾何表示形式,則 "()"的表示是一個1*1的方塊,高度為1; 2.對於一個括號序列A,"(A)"的表示是由一個比g(A)寬2個單位高1個單位的矩形包圍g(A),它的高度為A+1;
3.對於兩個括號序列A和B,A+B的幾何表示形式為把g(B)放置在g(A)右邊的一個單位,且高度為A和B的高度的較大值。
其中+指的是字符串的連接符。
在完成課件後,托米老師開始玩他做好的圖片。 他將圖像的有限區域交替地塗成黑色和白色,使最外面的區域全部塗成黑色。 對於上面的例子,這個著色如下所示:
現在給你一個合法的括號序列。 請計算顏色為黑色的區域的面積。
鏈接:https://www.nowcoder.com/acm/contest/111/A
來源:牛客網
作為故事主角的托米是一名老師。一天,他正在為解析算術表達式的課程準備課件。 在課程的第一部分,他只想專註於解析括號。 他為他的學生發明了一個有趣的正確括號序列的幾何表示,如下圖所示:
幾何表示的定義: 1. 對於一個括號序列A,我們定義g(A)是A的幾何表示形式,則 "()"的表示是一個1*1的方塊,高度為1; 2.對於一個括號序列A,"(A)"的表示是由一個比g(A)寬2個單位高1個單位的矩形包圍g(A),它的高度為A+1;
3.對於兩個括號序列A和B,A+B的幾何表示形式為把g(B)放置在g(A)右邊的一個單位,且高度為A和B的高度的較大值。
其中+指的是字符串的連接符。
現在給你一個合法的括號序列。 請計算顏色為黑色的區域的面積。
輸入描述:
輸入的第一行包含一個整數T,表示指定測試用例的數量。
每個測試用例前面都有一個空白行。
每個測試用例由一個合法括號序列組成。 每行只包含字符‘(‘和‘)‘。
輸出描述:
對於每個測試用例,輸出一行包含一個整數,表示相應幾何表示的黑色部分的面積。示例1
輸入
復制2 ((())) (())(()(()))
輸出
復制10 20
說明
第二個測試案例是上圖中顯示的案例。
備註:
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; }
括號匹配算面積(模擬)