D. Bracket Coloring

这篇具有很好参考价值的文章主要介绍了D. Bracket Coloring。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

题目链接:Problem - 1837D - Codeforces

题意理解:

判断是否可以将字符串s分成若干字子串,使每个子串或每个翻转的子串是合法的括号序列。

预备知识:

首先要知道如何判断一个括号序列是否是合法,共有两个条件:

1.左括号数=右括号数

2.对于任意位置i,i前的左括号数一定大于等于右括号数(即右括号数不大于左括号数)

解题思路:

这个字符串最终一定会分为两个部分,一部分是不翻转就合法的,另一部分是需要翻转才合法的(每部分都可能为空)。

思路一:

首先判断整个字符串是否是一个合法的括号序列,如果他不是,输出-1;

对于每一个位置,那么如果前面左括号多,那么将它放到无需翻转的子串中,否则,放到需要翻转的子串中。

但是感觉这种思路的合理性证明不好解释,又用了思路二。

代码:文章来源地址https://www.toymoban.com/news/detail-498617.html

#include<iostream>
using namespace std;

int T,n;
string s;
int ans[200005];

bool check()
{
    int l=0,r=0;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='(') l++;
        else r++;
    }

    if(l!=r) return  false;
    return true;
}
void solve()
{
    cin>>n>>s;

    //先进行合法性检验
    if(!check())
    {
        cout<<"-1"<<endl;
        return;
    }

    //初始化变量
    int l=0,r=0;
    for(int i=0;i<n;i++) ans[i]=0;

    //先找一段最长的RBS序列
    for(int i=0;i<n;i++)
    {
        if(s[i]=='(')
        {
            if(l>=r) ans[i]=1;
            else ans[i]=2;
            l++;
        }
        else
        {
            r++;
            if(l>=r) ans[i]=1;
            else ans[i]=2;
        }
    }

    int cnt=1;
    for(int i=1;i<n;i++)
    {
        if(ans[i]!=ans[0]) cnt=2;
    }

    cout<<cnt<<endl;
    if(cnt==1) for(int i=0;i<n;i++) cout<<"1 ";
    else for(int i=0;i<n;i++)
    {
        cout<<ans[i]<<" ";
    }
    cout<<endl;
}

int main()
{
    //freopen("D:\\data.txt","r",stdin);

    cin>>T;
    while(T--)
    {
        solve();
    }

    return 0;
}

思路二:

首先判断这个序列1.是否合法?2.是否可以用一种颜色填充。

合法:左括号数等于右括号数

一种颜色填充:保证任意位置左括号数始终大于右括号数(整个字符串是一个合法括号序列) 或者 保证任意位置右括号数始终大于左括号数(将整个字符串翻转,是一个合法括号序列)

否则,他就一定需要两种颜色填充。

那么就要找一个最长合法子串,开一个栈S,对于每个位置:

如果是左括号,那么就直接压进去;

如果是右括号,那么判断栈顶是否为左括号,如果是左括号,那么就与栈顶的左括号匹配,一起出栈;否则,他前面就没有左括号了,他就是需要翻转位置。

到最后,栈一定是栈顶都是左括号,栈底都是右括号,如:“)))(((”这样的形式。

将这些位置填充为颜色2

代码:

#include<iostream>
#include<stack>
using namespace std;

const int N = 200005;
int n,T;
string s;
int ans[N];
stack<int>S;

void solve()
{
    cin>>n>>s;

    //先判断两个问题:1.是否合法    2.是否可以用一种颜色填充
    int l=0,r=0;
    bool sv1=true,sv2=true;
    for(int i=0;i<n;i++)
    {
        if(s[i]=='(') l++;
        else if(s[i]==')') r++;

        if(r>l) sv1=false;
        if(l>r) sv2=false;
    }

    if(l!=r)
    {
        cout<<"-1"<<endl;
        return;
    }
    else if(sv1 || sv2) 
    {
        cout<<"1"<<endl;
        for(int i=0;i<n;i++) cout<<"1 ";
        cout<<endl;
        return;
    }

    for(int i=0;i<n;i++)
    {
        ans[i]=1;
        if(s[i]=='(') S.push(i);
        else
        {
            if(!S.empty() && s[S.top()]=='(') S.pop();
            else S.push(i);
        }
    }

    while(!S.empty())
    {
        ans[S.top()]=2;
        S.pop();
    }

    cout<<"2"<<endl;
    for(int i=0;i<n;i++) cout<<ans[i]<<" ";
    cout<<endl;
}

int main()
{
    //freopen("D:\\data.txt","r",stdin);

    cin>>T;
    while(T--) solve();

    return 0;
}

到了这里,关于D. Bracket Coloring的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • WiFi6的优势及BSS Coloring机制

    在802.11ac协议出现后,更广泛的会将它称为WiFi5,因此在11ac之后出现的802.11ax也就被称为WiFi6,并且是当前主流的技术之一。 那么在WiFi6中较WiFi5最为突出的几大优势如下: 引入了RU的概念,也就是OFDMA技术,相较于传统802.11的OFDM(频分复用)来说,这项技术大大提高了带宽的

    2024年02月05日
    浏览(35)
  • D. 1D Eraser

    time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output You are given a strip of paper s that is n cells long. Each cell is either black or white. In an operation you can take any k consecutive cells and make them all white. Find the minimum number of operations needed to remove all black cells. Inpu

    2024年02月08日
    浏览(45)
  • D. Lucky Permutation(置换环)

    D. Lucky Permutation 严格鸽题解大家可以看看这篇题解,有图片辅助,写的十分的好 题意:给我们一个数长度为n的数组,我们每次操作可以任选两个数进行交换。问我们最后得到满足逆序对是一的序列的最小操作次数是多少。 思路:我们不难知道每次交换两个相邻的数就会形成

    2023年04月16日
    浏览(66)
  • D. Maximum Distance(最小生成树)

    Problem - D - Codeforces   Chouti已经厌倦了乏味的作业,于是他打开了数年前创建的一个旧编程问题。 给定一个具有n个节点和m条加权边的连通无向图。其中有k个特殊节点:x1,x2,...,xk。 现在定义路径的成本为其边权的最大值。两个顶点之间的距离定义为连接它们的路径的最小成本

    2024年02月01日
    浏览(48)
  • D. Paths on the Tree

    Problem - 1746D - Codeforces 思路:先分析一下题意,根据第一条性质,每次只能够从1开始,而第二条性质则表明对于每个节点来说,经过这个节点的子节点的路径条数应该尽量均衡,最大值与最小值相差不能超过1,所以我们考虑,如果当前要选择k个路径,而当前节点有cnt个子节

    2024年02月09日
    浏览(36)
  • D. Li Hua and Tree(set操作)

    Problem - D - Codeforces   李华有一个有n个顶点和n -1条边的树。树的根是顶点1。每个顶点i的重要性为a。将子树的大小表示为该子树中顶点的数量,将重要性表示为该子树中顶点的重要性之和。将非叶顶点的重子结点表示为具有最大子树大小的子结点。如果存在多个重子,则重子

    2023年04月13日
    浏览(44)
  • CF1781 D. Many Perfect Squares [数学题]

    传送门:CF [前题提要]:一道有意思的数学题 直接想这道题是不好想的(博主当时就完全没有思路).那么 考虑将一个大问题分解成一个小问题想一下(感觉这种思考方式在CF题中还是挺常见的) ,考虑如果同时存在多个完全平方数,那么必然满足存在 两个完全平方数 .而当我们确定了

    2024年02月20日
    浏览(35)
  • CF1120 D. Power Tree 巧妙的图论转化

    传送门 [前题提要]:无 题目描述: 考虑对一个点的子树的所有 叶子节点 进行增减任意值.不难联想到对一个点的子树的 所有节点 增减任意值的做法.所以考虑使用类似于树链剖分的方式将树上修改化为链上区间修改. 考虑记录一个点的所有叶子节点,并且按照 d f s dfs df s 序将其

    2024年02月10日
    浏览(40)
  • D. More Wrong Codeforces Round 890 (Div. 2) 1856D

    Problem - D - Codeforces 题目大意:有一个隐藏的排列,给出其长度n,每次可以询问一个[l,r]区间内有多少逆序对,费用为,要求在总费用不超过的情况下输出最大值的下标 2=n=2000 思路:首先可以发现如果我们想要知道两个数a[i],a[j]的大小关系,只要知道[i,j]的逆序对数量和[i,j-

    2024年02月13日
    浏览(42)
  • Codeforces Round 935 (Div. 3) - D. Seraphim the Owl (动态规划)

    大家排成 n 人的队列,从 i=1 号开始,向猫头鹰谢拉菲姆请教生命的意义。不幸的是,基里尔当时正忙着为这问题编写传说,所以他来得晚了一些,站在了 n 这个人之后,排在了队伍的最后。基里尔对这种情况完全不满意,于是他决定贿赂一些排在他前面的人。 对于队列中的

    2024年04月17日
    浏览(55)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包