CF1709C Recover an RBS
题意
共 (
, )
和 ?
。你可以进行无限次操作,每次把一个 ?
换成一个 (
或者一个 )
。问是否有多种方法可以将这个字符串变为一个正确的括号序列。
解法
考虑贪心。
对于每一个字符串,我们不妨先找到其中一个正确的括号序列。假设最初这个字符串长度为 (
,)
。那么我们要将 ?
替换成 (
,把 ?
替换成 )
。
显然当一个字符串是一个括号序列时,对于每一位 (
的出现次数一定 )
出现的次数。并且最终 (
和 )
出现次数一样。
我们不妨找到 ?
变成 (
的所有字符中最靠后的一个和 ?
变成 )
最靠前的一个。交换这两个 (
和 )
。如果交换后这是一个合法括号序列,那么至少有两种合法方案,如果不合法,则只有一种合法方案。
接下来考虑证明:
假设找到的两个位置为
代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
using namespace std;
int t;
string s;
inline bool check(string p)
{
int c1 = 0, c2 = 0, l = p.size() - 1;
for (int i = 0; i <= l; i++)
{
c1 += p[i] == '(';
c2 += p[i] == ')';
if (c1 < c2) return 0;
}
if (c1 != c2) return 0;
return 1;
}
int main()
{
ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
cin >> t;
while (t--)
{
cin >> s;
int l = s.size() - 1;
int c1 = count(s.begin(), s.end(), '('), c2 = count(s.begin(), s.end(), ')');
string copy = s;
int pl = 0, pr = 0;
for (int i = 0; i <= l; i++)
{
if (copy[i] == '?' && c1 + 1 <= (l + 1) / 2) copy[i] = '(', c1++, pl = i;
else if (copy[i] == '?')
{
copy[i] = ')', c2++;
if (!pr) pr = i;
}
}
string h = copy;
swap(copy[pl], copy[pr]);
if (h != copy && check(copy))
{
printf("NO\n");
}
else printf("YES\n");
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现