日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces Round #529 (Div. 3) E. Almost Regular Bracket Sequence (括号配对,前缀和)

發布時間:2024/4/18 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces Round #529 (Div. 3) E. Almost Regular Bracket Sequence (括号配对,前缀和) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

翻轉一個括號使得所有括號都能配對,問一共可以翻轉幾個括號。

AC

方法1:

  • 如果某個位置上的右括號數量大于他的左括號的數量那么這個位置及之后的位置無論如何翻轉都不能滿足配對。
    例如:())((() 第三個位置:右括號2個,左括號1個,位置3之后的括號無論如何變化,第三個位置上的狀態都不會改變。

  • 同理如果從右邊開始考慮,如果某個位置上的右括號數量小于左括號數量,之后位置上的括號也是不能匹配
    例如:((()(() 第五個位置:右括號1個,左括號兩個。那么位置5之前的括號無論如何變化,位置5的狀態都不會改變。

  • 為什么考慮左右的不考慮當下的?因為:雖然當前位置不符合匹配的要求“(()”,但是我可以通過翻轉改變呀。

  • 用L,R數組記錄括號前后綴數量和,之后枚舉每個括號,判斷能否翻轉使得匹配

方法2:

  • 要想翻轉一個使得整體括號匹配,只能多出來2個左括號或者2個右括號
  • 假如多2個左括號,我們最左邊開始判斷,如果當前位置為左括號且左括號的前綴和大于等于2,那么翻轉這個位置就可以使得整個括號匹配。
  • 假如多2個右括號,我們最左邊開始判斷,如果當前位置為右括號且左括號的前綴和大于等于-2,那么翻轉這個位置就可以使得整個括號匹配。
  • 當我們求完前綴和之后,需要從后向前更新最小值,這樣能保證翻轉前面的區間的同時后面的區間也能滿足。
#include <bits/stdc++.h> #define LL long long #define P pair<int, int> #define lowbit(x) (x & -x) #define mem(a, b) memset(a, b, sizeof(a)) #define REP(i, n) for (int i = 1; i <= (n); ++i) #define rep(i, n) for (int i = 0; i < (n); ++i) #define N 1000005 using namespace std;int L[N], R[N]; int Fl[N], Fr[N]; char s[N]; int main() { #ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin); #endifint n;while (scanf("%d%s", &n, s+1) != EOF) {Fl[0] = 1;Fr[n+1] = 1;mem(L, 0);mem(R, 0);// 求左括號前綴和,并判斷當前位置是否可以翻轉for (int i = 1; i <= n; ++i) {if (s[i] == '(') L[i] = L[i-1] + 1;else L[i] = L[i-1] - 1;Fl[i] = (Fl[i-1] && L[i] >= 0);}// 求右括號后綴和,并判斷當前位置是否可以翻轉for (int i = n; i >= 1; --i) {if (s[i] == ')') R[i] = R[i+1] + 1;else R[i] = R[i+1] - 1;Fr[i] = (Fr[i+1] && R[i] >= 0);}int ans = 0;for (int i = 1; i <= n; ++i) {if (Fl[i-1] == 0) {break;}if (Fr[i+1] == 0) {continue;}if (s[i] == ')' && L[i-1] + 1 == R[i+1]) ans++;else if (s[i] == '(' && L[i-1] == R[i+1] + 1) ans++;}cout << ans << endl;}return 0; } #include <bits/stdc++.h> #define LL long long #define P pair<int, int> #define lowbit(x) (x & -x) #define mem(a, b) memset(a, b, sizeof(a)) #define REP(i, n) for (int i = 1; i <= (n); ++i) #define rep(i, n) for (int i = 0; i < (n); ++i) #define N 1000005 using namespace std;int L[N]; char s[N]; int main() { #ifndef ONLINE_JUDGEfreopen("in.txt", "r", stdin); #endifint n;while (scanf("%d%s", &n, s+1) != EOF) {REP (i, n) L[i] = L[i-1] + (s[i] == '(' ? 1 : -1);if (L[n] != -2 && L[n] != 2) {puts("0");continue;}for (int i = n-1; i >= 1; --i) L[i] = min(L[i], L[i+1]);int cnt = 0;int ans = 0;REP (i, n) {if (s[i] == '(') {if (L[i] >= 2 && L[n] == 2) ans++;cnt++;}else{if (L[i] >= -2 && L[n] == -2) ans++;cnt--;}// 如果右括號已經比左括號 后面就不會有解if (cnt < 0) break;}printf("%d\n", ans);}return 0; }

總結

以上是生活随笔為你收集整理的Codeforces Round #529 (Div. 3) E. Almost Regular Bracket Sequence (括号配对,前缀和)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。