zoukankan      html  css  js  c++  java
  • #4 div1E Parentheses 括号匹配

    E - Parentheses
    Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu

    Description

    E - Parentheses

    Problem Statement

    You are given nn strings str1,str2,,strnstr1,str2,…,strn, each consisting of ( and ). The objective is to determine whether it is possible to permute the nnstrings so that the concatenation of the strings represents a valid string.

    Validity of strings are defined as follows:

    • The empty string is valid.
    • If AA and BB are valid, then the concatenation of AA and BB is valid.
    • If AA is valid, then the string obtained by putting AA in a pair of matching parentheses is valid.
    • Any other string is not valid.

    For example, "()()" and "(())" are valid, while "())" and "((()" are not valid.

    Input

    The first line of the input contains an integer nn (1n1001≤n≤100), representing the number of strings. Then nn lines follow, each of which contains stristri (1stri1001≤∣stri∣≤100). All characters in stristri are ( or ).

    Output

    Output a line with "Yes" (without quotes) if you can make a valid string, or "No" otherwise.

    Sample Input 1

    3
    ()(()((
    ))()()(()
    )())(())

    Output for the Sample Input 1

    Yes

    Sample Input 2

    2
    ))()((
    ))((())(

    Output for the Sample Input 2

    No
    题意:每出现一对()时可以消去,现在给你n个由(和)组成的字符串,问能否通过安排这个n个字符串的位置使得
    最后没有任何字符留下;
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const int  inf =0x7f7f7f7f;
    const double pi=acos(-1);
    const int maxn=40000;
    
    struct node {
       int x,y;
       bool operator<(const node&a) const{
           return this->x<a.x;
       }
    };
    vector<node> A,B;
    char s[10000];
    int main()
    {
        int n;
        while(~scanf("%d",&n))
        {
            A.clear();B.clear();
            for(int i=1;i<=n;i++)
            {
                scanf("%s",s);
                int l=0,r=0;
                for(int j=0;s[j]!='';j++)
                {
                     if(s[j]=='(') r++;
                     else if(!r) l++;
                     else r--;
                }
                if(l>r) B.push_back(node{r,l-r});
                else  A.push_back((node){l,r-l});
            }
    
            sort(A.begin(),A.end());
            sort(B.begin(),B.end());
            int cntA=0,cntB=0;
    
            bool flag=true;
            for(int i=0;i<A.size();i++)
            {
                if(A[i].x>cntA) {flag=false;break;}
                cntA+=A[i].y;
            }
    
            for(int i=0;i<B.size();i++)
            {
                if(B[i].x>cntB) {flag=false;break;}
                cntB+=B[i].y;
            }
    
            if(cntA!=cntB) flag=false;
            printf("%s
    ",flag?"Yes":"No");
        }
        return 0;
    }
    
    分析:这道题做了很久,其实我的思路大部分是正确的,有几个值得改进的地方:
    1.字符串的处理上,我是直接对字符进行移动,而简洁的做法就是直接统计;
    我的
    
    
    while(1)
        {
            int flag=0;
            for(int i=0;s[i+1]!='';i++)
            {
                if(s[i]=='('&&s[i+1]==')')
                    {
                          int j;
                          for(j=i+2;s[j]!='';j++)
                              s[j-2]=s[j];
                          s[j-2]='';
                          flag=1;
                    }
                if(flag) break;
            }
            if(!flag) return;
        }
    
    
    

      简洁:

    for(int j=0;s[j]!='';j++)
                {
                     if(s[j]=='(') r++;
                     else if(!r) l++;
                     else r--;
                }
    

      2.最后对右边的处理也不是任意的,比如(((((和右边的)))( ,))))((( , ))左边的与右边的不能任意结合

    我的wa代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <stack>
    #include <map>
    #include <algorithm>
    #include <set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long Ull;
    #define MM(a,b) memset(a,b,sizeof(a));
    const double eps = 1e-10;
    const int  inf =0x7f7f7f7f;
    const double pi=acos(-1);
    const int maxn=40000;
    
    char s[100000+10];
    int cntl[14],cntr[14],n,l=0,r=0,kk,p,flag[15],used[15];
    
    void init()
    {
        while(1)
        {
            int flag=0;
            for(int i=0;s[i+1]!='';i++)
            {
                if(s[i]=='('&&s[i+1]==')')
                    {
                          int j;
                          for(j=i+2;s[j]!='';j++)
                              s[j-2]=s[j];
                          s[j-2]='';
                          flag=1;
                    }
                if(flag) break;
            }
            if(!flag) return;
        }
    }
    
    struct node{
        int id,cntr;
    };
    bool operator<(node a,node b)
    {
         return a.cntr<b.cntr;
    }
    void solve()
    {
        int l=0;
        for(int i=1;i<=n;i++)
          if(cntl[i]&&!cntr[i]) {l+=cntl[i];used[i]=1;}
    
        if(l==0) {printf("No
    ");return;}
    
        priority_queue<node> q;
        for(int i=1;i<=n;i++)
            if(!used[i]&&cntl[i]>=cntr[i])
               q.push((node){i,cntr[i]});
    
        while(q.size())
        {
            node u=q.top();q.pop();
            int i=u.id;
            if(l<cntr[i]) {printf("No
    ");return;}
            l+=cntl[i];
            l-=cntr[i];
            used[i]=1;
        }
    
        for(int i=1;i<=n;i++)
          if(!used[i]&&cntl[i])
          {
               if(l<cntr[i]) {printf("No
    ");return;}
               l-=cntr[i];
               l+=cntl[i];
               used[i]=1;
          }
    
        for(int i=1;i<=n;i++)
           if(!used[i])
        {
             if(l<cntr[i]) {printf("No
    ");return;}
             l-=cntr[i];
             used[i]=1;
        }
        if(l) {printf("No
    ");return;}
        else   {printf("Yes
    ");return;}
    }
    
    int main()
    {
        while(~scanf("%d",&n))
        {
           MM(cntl,0);MM(cntr,0);MM(used,0);
           p=n;l=r=kk=0;
           for(int k=1;k<=n;k++)
           {
               scanf("%s",s);
               init();
               for(int i=0;s[i]!='';i++)
                  if(s[i]=='(') cntl[k]++;
                   else if(s[i]==')') cntr[k]++;
               if(!cntl[k]&&!cntr[k]) p--;
           }
           if(p==0) {printf("Yes
    ");continue;}
           solve();
        }
        return 0;
    }
    

      

     

      

     
  • 相关阅读:
    浅析软件开发项目的前期沟通工作
    .net core 和 WPF 开发升讯威在线客服系统:实现对 IE8 的完全完美支持 【干货】
    产品的定价策略(一):想通过产品挣钱,首先你产品的目标客户得不差钱
    .net core 和 WPF 开发升讯威在线客服系统:使用线程安全的 BlockingCollection 实现高性能的数据处理
    .net core 和 WPF 开发升讯威在线客服系统:使用 TCP协议 实现稳定的客服端
    .net core 和 WPF 开发升讯威在线客服系统:使用 WebSocket 实现访客端通信
    Centos上配置两层nginx转发,把请求转发到外网
    真实字节二面:什么是伪共享?
    关于MVCC,我之前写错了,这次我改好了!
    从家庭主妇到格力老总,董明珠的大女主逆袭之路
  • 原文地址:https://www.cnblogs.com/smilesundream/p/5672686.html
Copyright © 2011-2022 走看看