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
4
())(
4
()()
6
)))(((
Sample Output
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;
}
边想边写的,所以最后写的有些啰嗦,应该可以更精减