题目的意思读了我半天......意思就是说遇见左括号加一,遇见右括号减一,现在给你一个打乱了的数字序列,让你输出一个字典序最小的括号序列。
我们考虑一个贪心,先贪左括号,然后判断右括号,一看代码很明显的就懂了。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
using namespace std;
map<int ,int>mp;
int a[200000];
int main(){
int t;
int cnt=0;
scanf("%d",&t);
while(t--){
cnt++;
int n;
printf("Case %d: ",cnt);
mp.clear();
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
mp[a[i]]++;
}
if((n&1)||!mp.count(1)){
printf("invalid\n");
continue;
}
bool flag=true;
mp[1]--;
int pos=1;
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=false;
}
if(!flag&&pos){
printf("invalid\n");
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)){
pos++;
mp[pos]--;
printf("(");
}
else if(mp[pos-1]&&mp.count(pos-1)){
pos--;
mp[pos]--;
printf(")");
}
}
cout<<endl;
}
return 0;
}