您的位置:首页 > 大数据 > 人工智能

2016 Multi-University Training Contest 8(2016多校训练第八场)1011

2016-08-11 21:06 405 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5831

题目大意:给定一个由左右括号构成的字符序列,如果所有的左括号都能有一个右括号与之对应,则认为该序列是“正确的”,现在给出若干这样的序列,当然它们有可能是正确的,也有可能是不正确的,问,是否能通过其中两个字符的交换使得这个字符序列成为“正确的”(对于一个本来就正确的序列,也必须执行一次交换,也就是说对任何的序列必须且只需执行一次交换操作)。

解题思路:对于左右括号匹配的问题,首先想到的就是用栈来处理,因此,当我们得到一个字符序列的时候,就将它们一个个地压入栈中,若有能匹配的左右括号,则将这一对括号出栈,再继续将剩下的字符压栈,这样一来,栈中剩下的就是不能匹配的括号,通过判断剩下括号的数量以及情形来判断,思路如下:

(1)若剩余符号数为奇数,则必然不可能通过位置的调整得到“正确”序列;

(2)若剩余符号数大于或者等于6时,因为不匹配的括号太多,也不可能通过一次调整得到正确序列;

(3)若剩余符号数为4时,只有一种排列方式:))((,对于这种方式,只要将第一个括号与最后一个括号交换即可得到正确序列,因此,若剩余括号数为4时直接输出yes;

(4)若剩余符号数为2时,可能为: ) (  ,  ) )   ,   ( (,只有第一种情况可得到正确序列,特判即可

通过这四种情况的判断即可覆盖所有可能性,用代码实现即可

AC代码:
#include <iostream>
#include <stack>
using namespace std;
int main()
{
int t;
int n;
char c[100005];
cin>>t;
while(t--)
{
stack<char> ss;
ss.push('#');
cin>>n;
if(n==2)
{
char a,b;
cin>>a>>b;
if(a==')'&&b=='(')
{
cout<<"Yes"<<endl;
continue;
}
else
{
cout<<"No"<<endl;
continue;
}
}
else
{
cin>>c;
for(int i=0;i<n;i++)
{
char temp = ss.top();
if(temp=='('&&c[i]==')')ss.pop();
else ss.push(c[i]);
}
int len = ss.size()-1;
if(len>4)
{
cout<<"No"<<endl;
continue;
}
else if(len%2!=0)
{
cout<<"No"<<endl;
continue;
}
else if(len==4)
{
int lcnt=0;
int rcnt=0;
char str[4];
for(int i=3;i>=0;i--)
{
str[i] = ss.top();
if(str[i]=='(')lcnt++;
else rcnt++;
ss.pop();
}
if(lcnt!=rcnt)
{
cout<<"No"<<endl;
continue;
}
else
{
cout<<"Yes"<<endl;
continue;
}
}
else if(len==2)
{
int lcnt=0;
int rcnt=0;
char str[2];
for(int i=1;i>=0;i--)
{
str[i] = ss.top();
if(str[i]=='(')lcnt++;
else rcnt++;
ss.pop();
}
if(lcnt!=rcnt)
{
cout<<"No"<<endl;
continue;
}
else
{
cout<<"Yes"<<endl;
continue;
}
}
else
{
cout<<"Yes"<<endl;
continue;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  杭电 算法 acm
相关文章推荐