uvalive – 7637 e – balanced string(构造)

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

#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 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 ()
{
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;
}