Problem 1011 Rikka with Parenthesis II

2 篇文章 0 订阅
1 篇文章 0 订阅

Problem 1011 Rikka with Parenthesis II

Accept: 0    Submit: 0
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit : 65536/65536 K (Java/Others)

 Problem Description

As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Correct parentheses sequences can be defined recursively as follows:

1.The empty string "" is a correct sequence.

2.If "X" and "Y" are correct sequences, then "XY" (the concatenation of X and Y) is a correct sequence.

3.If "X" is a correct sequence, then "(X)" is a correct sequence.

Each correct parentheses sequence can be derived using the above rules.

Examples of correct parentheses sequences include "", "()", "()()()", "(()())", and "(((())))".

Now Yuta has a parentheses sequence S, and he wants Rikka to choose two different position i,j and swap Si,Sj. 

Rikka likes correct parentheses sequence. So she wants to know if she can change S to a correct parentheses sequence after this operation.

It is too difficult for Rikka. Can you help her?

 Input

The first line contains a number t(1<=t<=1000), the number of the testcases. And there are no more then 10 testcases with n>100

For each testcase, the first line contains an integers n(1<=n<=100000), the length of S. And the second line contains a string of length S which only contains ‘(’ and ‘)’.

 Output

For each testcase, print "Yes" or "No" in a line.

 Sample Input

3
4
())(
4
()()
6
)))(((

 Sample Output

Yes
Yes
No

Hint

For the second sample input, Rikka can choose (1,3) or (2,4) to swap. But do nothing is not allowed.

 Problem Idea

解题思路:

【题意】
给一串只有左括号和右括号组成的字符串,问在交换并且只能交换两个字符之后,括号是否能匹配

【类型】

【思路】

既然是括号区配,自然就会想到栈(stack),当然也可以用数组来实现。

左括号直接进栈,右括号正常情况下不进栈,只弹出栈顶的左括号,表示一对括号配对成功

如果最后栈为空,则表示括号全部配对,有一种情况例外,就是(),因为不交换也不行。

栈不为空,有两种情况是可以输出Yes的,一个是)(,另一个是))((,开始没想到后一种情况,导致程序WA。

其他的情况则为No.

【代码】

#include <iostream>
#include <stack>
using namespace std;
int t,n,f,k,s;
char ch;
int main()
{
cin>>t;
while(t--)
{
stack <char> st;//栈的定义必须写在循环体内,保证每次循环开始栈为空 
k=0;
s=0;
f=0; //每次循环开始都必须初始化,所以不能写在外面 
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>ch; //逐个输入字符 
if(ch=='(') //如果是左括号 
{
   st.push(ch);//直接进栈 
   s++;
}
else
 if(!st.empty()&&st.top()=='(')  //如果是右括号,并且栈中已经有左括号,则弹出左括号 
 {
    st.pop();
    s--;
    k++; //至少要弹出两次,否则只有一对括号也是错的 
 }
 else
 {
    st.push(ch);//如果没有配对的左括号,则右括号进栈 
    f++; //右括号正常情况下是不进栈的,所以进栈一次就计一次,最多只能有一个右括号进栈 
 }
}
if(st.empty()&&(k>=2)||f==2&&s==2)//如果栈空,表示全部配对,k>=2,表示至少有两对,因为如果不交换也是错 
 cout<<"Yes\n";
else if(st.size()!=2)//针对样例一,最后如果栈里不是两个括号,就肯定错了 
       cout<<"No\n";
    else if(f==1)//如果栈中只有两个括号,并且右括号只有一个,则是对的,否则就是错的 
            cout<<"Yes\n";
         else
            cout<<"No\n";
}
return 0;
}

边想边写的,所以最后写的有些啰嗦,应该可以更精减

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值