zoukankan      html  css  js  c++  java
  • 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("*********
    ");
    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 <<"
    ";
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    usaco dec 2012 first!
    uva 1449
    unity3D学习笔记之DOTween插件的学习(持续更新)
    中南林业科技大学第十一届程序设计大赛 G 0和5
    中南林业科技大学第十一届程序设计大赛 D 最大的湖
    最小生成树之克鲁斯卡尔(Kruskal)算法
    最小生成树Prim算法理解
    判断无向图是否联通模板(并查集版)(DFS),BFS等其他方法将陆续更新
    矩阵压缩学习笔记
    C/C++ assert()函数用法总结
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9357541.html
Copyright © 2011-2022 走看看