2018 Multi-University Training Contest 1-1002 -Balanced Sequence(括号匹配+贪心)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6299
题目:
题意:t组数据,每组数据给你一个n表示给你n个括号串,这n个括号串之间进行组合,求能够匹配的长度。
思路:用一个结构体来记录每个字符串的左括号和右括号的数量,在输入时将同串中能够匹配的直接消掉,最后剩余的字符绝对是所有的右括号在左边,左括号在右边,假设当前字符串为())(()(,我们一次将其标记为1~7,那么1和2可以匹配,5可以和6匹配,最后剩余347,也就是)((。我们紧接着就对n个形如刚刚例子中的347这样的括号进行贪心,排序即可(排序分析见代码注释)。
代码实现如下:
1 #include <set> 2 #include <map> 3 #include <queue> 4 #include <stack> 5 #include <cmath> 6 #include <bitset> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstdlib> 11 #include <cstring> 12 #include <iostream> 13 #include <algorithm> 14 using namespace std; 15 16 typedef long long ll; 17 typedef unsigned long long ull; 18 19 #define bug printf("*********\n"); 20 #define FIN freopen("D://code//in.txt", "r", stdin); 21 #define debug(x) cout<<"["<<x<<"]" <<endl; 22 #define IO ios::sync_with_stdio(false),cin.tie(0); 23 24 const double eps = 1e-8; 25 const int mod = 1e9 + 7; 26 const int maxn = 1e5 + 7; 27 const double pi = acos(-1); 28 const int inf = 0x3f3f3f3f; 29 const ll INF = 0x3f3f3f3f3f3f3f3f; 30 31 inline int read() {//读入挂 32 int ret = 0, c, f = 1; 33 for(c = getchar(); !(isdigit(c) || c == '-'); c = getchar()); 34 if(c == '-') f = -1, c = getchar(); 35 for(; isdigit(c); c = getchar()) ret = ret * 10 + c - '0'; 36 if(f < 0) ret = -ret; 37 return ret; 38 } 39 40 41 int t, n, ans; 42 string s; 43 44 struct node { 45 int p, q; //p为左括号数,q为右括号数,看那个半圆朝向是不是非常生动形象~ 46 bool operator < (const node& x) const {//排序只需比较两个即可, 47 //因为相互之间比较都是一对一,所以在此处将所有可能的情况列举出来即可; 48 if(q >= p && x.q < x.p) return false; //当前的左括号数小于等于右括号数,x的右括号数小于左括号数,那么要想匹配的更多 49 //肯定是x排在前面; 50 if(q < p && x.q >= x.p) return true; //与上面情况刚好相反; 51 if(q >= p && x.q >= x.p) return p > x.p;//都是右括号数大于等于左括号数,那么就想象是最后两个进行比较,为了能够匹配更多 52 //那么最后一个的左括号数一定要最少,前面的同理; 53 return q < x.q; //情况与上述相反,可以想象是第一个和第二个比较。 54 } 55 }a[maxn]; 56 57 int main() { 58 IO; 59 //FIN; 60 cin >>t; 61 while(t--) { 62 cin >>n; 63 ans = 0; 64 for(int i = 0; i < n; i++) { 65 cin >>s; 66 a[i].p = a[i].q = 0; 67 for(int j = 0; j < s.size(); j++) { 68 if(s[j] == '(') a[i].p++; //将所有的左括号记录下来; 69 if(s[j] == ')') { 70 if(a[i].p > 0) { //当前右括号前面还有左括号没有匹配,那么不记录当前的右括号, 71 //并将前面的左括号数减一,相当于匹配了一对括号; 72 a[i].p--; 73 ans += 2; 74 } 75 else a[i].q++; //否则就记录右括号 76 } 77 } 78 } 79 sort(a, a + n); 80 int nw = 0; //记录前面还有多少个左括号没有匹配,因为括号匹配间没要求是连续的,所以当前的右括号可以匹配上上个括号 81 for(int i = 0; i < n; i++) { 82 if(a[i].q > nw) a[i].q = nw; 83 ans += a[i].q * 2; 84 nw -= a[i].q; 85 nw += a[i].p; 86 } 87 cout <<ans <<"\n"; 88 } 89 return 0; 90 }
版权声明:本文允许转载,转载时请注明原博客链接,谢谢~