Educational Codeforces Round 132 (Rated for Div. 2) C. Recover an RBS

 

 翻译:

括号序列是只包含字符"("和")"的字符串。正则括号序列(或简称RBS)是一个可以通过在序列的原始字符之间插入字符“1”和“+”转换为正确算术表达式的括号序列。例如:

括号序列"()()"和"(())"是正则表达式(得到的表达式是"(1)+(1)"和"((1+1)+1)");
括号序列")(","("和")"不是。
有苏格兰皇家银行。一些括号已被问号取代。是否有一种独特的方法可以用括号替换问号,从而得到一个RBS序列?

输入
第一行包含单个整数𝑡(1≤𝑡≤5⋅104)——测试用例的数量。

每个测试用例的唯一一行包含一个RBS,其中一些括号被问号替换。每个字符都是'(',')'或'?'。至少可以从给定的序列中恢复一个RBS。

所有测试用例中序列的总长度不超过2⋅105。

输出
对于每个测试用例,如果用括号替换问号的方法是惟一的,则打印“YES”,这样得到的序列是一个RBS。如果有不止一种方法,那么打印“NO”。

例子
inputCopy
5
(?))
??????
()
??
(?) () ?)
outputCopy
是的
没有
是的
是的
没有
请注意
在第一个测试用例中,唯一可能的原始RBS是“(())”。

在第二个测试用例中,有多种恢复RBS的方法。

在第三和第四个测试用例中,唯一可能的原始RBS是“()”。

在第五个测试用例中,原始RBS可以是“((()())”或“(())()()”。

思路:直接记录 ( ,),?的数量。如果(,)的数量到达了一半,则剩下的就可以确定,所以我们直接进行枚举,如果?放置括号的方法不唯一,可以交换最后一个(,和第一个)来判断,因为(在前面,后面必有)来匹配,然后计算前缀来判断即可。

代码:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <stdio.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<tuple>
#include<numeric>
#include<stack>
using namespace::std;
typedef long long  ll;
int n,t;
inline __int128 read(){
    __int128 x = 0, f = 1;
    char ch = getchar();
    while(ch < '0' || ch > '9'){
        if(ch == '-')
            f = -1;
        ch = getchar();
    }
    while(ch >= '0' && ch <= '9'){
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}
inline void print(__int128 x){
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        print(x / 10);
    putchar(x % 10 + '0');
}

string s;
string a;
string d;
void solv(){
    cin>>s;
    int bj=0;
    int bjz=0;
    int bjy=0;
    int an=0;
    if (s.size()==2) {
        printf("YES\n");return;
    }
    for (int i =0; i<s.length(); i++) {
        if (s[i]=='?') {
            an++;
        }
        if (s[i]=='(') {
            bjz++;
        }
        if (s[i]==')') {
            bjy++;
        }
    }
    if (an==0||an==1||bjz==s.size()>>1||bjy==s.size()>>1) {
        
        printf("YES\n");return;
    }
    if (an==s.size()) {
        printf("NO\n");return;
    }
    int jk=-1,kj=-1;
    for (int i =0; i<s.size(); i++) {
        if (s[i]=='?'&&bjz!=s.size()>>1) {
            s[i]='(';
            jk=i;
            bjz++;
            continue;
        }
        if (s[i]=='?') {
            s[i]=')';
            if (kj==-1) {
                kj=i;
            }
        }
    }
    swap(s[jk], s[kj]);
    ll sd=0;
    for (int i =0; i<s.size(); i++) {
        if (s[i]=='(') {
            sd++;
        }
        else{
            sd--;
        }
        if (sd<0) {
            
            printf("YES\n");return;
        }
    }
    printf("NO\n");
    
    
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(); cout.tie();
    cin>>t;
    while (t--) {
        solv();
    }
    return 0;
}
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值