Problem Statement

题目链接:https://vjudge.net/contest/239445#problem/E

 
 

E -

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 nn strings 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 (1|stri|1001≤|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<stdio.h>
#include<string.h>
#include<cmath>
#include<math.h>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const ll mod=1e9+7;
const int maxn=2e2+10;
const int maxk=100+10;
const int maxx=1e4+10;
const ll maxe=1000+10;
#define INF 0x3f3f3f3f3f3f
typedef pair<int,int>P;//用来存储有多少个(和)first是(的个数,second是)的个数
P p[maxk];
char s[maxk];
bool vis[maxk];
int n;
P solve(char s[])//这一步操作是消去本来该字符串就能消去的()
{//这里学到了,竟然是用pair型来定义函数,长见识了
    int l=0,r=0;
    for(int i=0;s[i];i++)
    {
        if(s[i]=='(') l++;
        else if(l) l--;
        else r++;
    }
    return P(l,r);//返回值也应当是pair型
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    int cnt=0;//用来存储只有(的字符串中( 的总个数
    for(int i=0;i<n;i++)
    {
        cin>>s;
        p[i]=solve(s);
        if(!p[i].second) cnt+=p[i].first,i--,n--;//存储下来了直接删掉
    }
    int ans=0,ret=1;//ans用来存储有多少个)
    memset(vis,false,sizeof(vis));//用来标记字符串是否已经用过了
    int mx,id;
    for(int i=0;i<n&&ret;i++)
    {
        mx=-120,id=-1;
        for(int j=0;j<n;j++)
        {
            if(vis[j]||ans<p[j].first) continue;//这里为何要ans>p[j].first,因为如果>的话,那么本个字符串后面的(全部可以消除
            int k=p[j].second-p[j].first;//这是消去了(还剩多少个)
            if(k>mx)
            {
                mx=k;
                id=j;//这里用到了点贪心,就是每次都保留最多的),
            }
        }
        if(id==-1) ret=0;//如果还没到最后一个字符串就已经没有选择了,代表消不了,直接退出
        vis[id]=true;
        ans+=mx;
    }
    if(ans==cnt&&ret) cout<<"Yes"<<endl;//不仅仅ans=cnt,ret也要刚好为1
    else
        cout<<"No"<<endl;
    return 0;
}
当初的梦想实现了吗,事到如今只好放弃吗~
原文地址:https://www.cnblogs.com/caijiaming/p/9383315.html