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

题目链接: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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值