UVALive

原题链接

题意:给出一个打乱顺序的序列,问是否能构造出一个括号匹配的字符串。每个数字为此前读取到的左括号数减去右括号数。

分析:有左括号开始构造,不够的话就找右括号。注意特殊情况待处理。详情看代码

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<cstdlib>
#include<climits>
#include<ctype.h>
#include<set>
#include<map>
#define pi acos(-1.0)
#define mem(a) memset(a,0,sizeof(a))
#define mems(a,b) memset((a),(b),sizeof(a))
#define ll long long
#define ull unsigned long long
//#define LOCAL
#define ls root<<1
#define rs root<<1|1
#define Ls root<<1,l,mid
#define Rs root<<1|1,mid+1,r
using namespace std;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
map<int,int>mp;
int a[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    int kase=0;
    while(t--){
        int n;
        scanf("%d",&n);
        mp.clear();
        for(int i=0;i<n;i++) scanf("%d",&a[i]),mp[a[i]]++;
        printf("Case %d: ",++kase);
        if((n&1)&&!mp.count(1)){
            puts("invalid");
            continue;
        }
        mp[1]--;
        int pos=1,flag=0;
        for(int i=1;i<n&&!flag;i++){
            if(mp[pos+1]&&mp.count(pos+1)){
                pos++;
                mp[pos]--;
            }else if(mp[pos-1]&&mp.count(pos-1)){
                pos--;
                mp[pos]--;
            }
            else flag=1;
        }
        if(flag&&pos){
            puts("invalid");
            continue;
        }
        mp.clear();
        for(int i=0;i<n;i++) mp[a[i]]++;
        printf("(");
        pos=1;
        for(int i=1;i<n;i++){
            if(mp[pos+1]&&mp.count(pos+1)){
                printf("(");
                pos++;
                mp[pos]--;
            }else if(mp[pos-1]&&mp.count(pos-1)){
                pos--;
                mp[pos]--;
                printf(")");
            }
        }
        puts("");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fht-litost/p/7282540.html