题意:有一个只包含 ‘(’‘)’ 的序列,选两个位置进行一次交换,问是否能构成合法序列?
思路:
遍历,遇到“("时,a++,遇到“)"时,若a>0,说明有正常的左括号与右括号匹配,若a<=0,说明匹配不上,b++;
遍历结束后,若 a==0,b==0,说明全正常,YES
a==1,b==1,说明有一对不匹配 ) ( ,YES
a==2,b==2,说明有两对不匹配 ) ) ( ( ,交换第一个与最后一个即可,YES,一开始忽略这种情况了。
注意只有两个字符 ( ) 时,必须交换一次,所以NO。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define eps 1e-8
#define maxn 150
#define mod 110119
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;
int main(){
// IN;
int t;
int n;
int a=0,b=0;
cin>>t;
char str[100000+5];
while(t--){
scanf("%d",&n);
if(n==0){
printf("Yes\n");
continue;
}
scanf("%s",str);
a=0;
b=0;
int len=strlen(str);
if(n==2 && str[0]=='(' &&str[1]==')'){
printf("No\n");
continue;
}
for(int i=0;i<n;i++){
if(str[i]=='(')
a++;
else{
if(a>0){
a--;
}else{
b++;
}
}
}
if( (a==1 && b==1) || (a==0 && b==0 )|| (a==2 && b==2) )
printf("Yes\n");
else
printf("No\n");
}
}