牛客网 提高组第8周 T1 染色

染色

链接:

https://ac.nowcoder.com/acm/contest/176/A

来源:牛客网

题目描述

( t{fizzydavid})( t{leo})(n)个方格排成一排,每个方格初始是白色。( t{fizzydavid})有红色染料,( t{leo})有蓝色染料。他们共进行了(m)次操作,在每次操作中,( t{fizzydavid})或者( t{leo})会选择若干个(可以是零个)连续相邻的方格并用自己的染料给这些格子染色。当一个格子被染成某个颜色时,这种染料会覆盖之前这个格子上的颜色。

现在你并不知道他们每次操作选择了哪些格子,只知道每次操作是谁进行的,以及最终这 (n)个方格的颜色。你需要判断是否存在某种选择格子的方式使得操作完之后(n)个方格的颜色与给定的相同。你还发现,(n)个格子最终都不是白色。

输入描述:

第一行包含一个整数(T),表示本组数据共有(T)组测试点。

对每组测试点的第一行是一个由(R)(B)组成的字符串(s)表示最终格子的颜色。(R)表示红色,(B)表示蓝色,同时字符串的长度为(n)

第二行是一个由(F)(L)组成的字符串(t)表示(m)次操作,(F)表示某次是( t{fizzydavid})操作,(L)表示是( t{leo})操作,同时字符串的长度为(m)

输出描述:

对每组测试点输出一行,如果满足条件输出( t{Yes})否则输出( t{No})

说明

所有数据满足(Tle 20)

(50\%)的数据满足(n,mle 15)

(80\%)的数据满足(n,mle 100)

(100\%)的数据满足(n,mle 100000)


恩,啥也没想到,一开始就没想到要倒着做。

考虑倒着操作,那么颜色是不会覆盖原来的颜色的。那么每个格子显然只会最开始被染上一次颜色,且这个颜色必须是要求的颜色。

很自然的把连续的颜色区间缩成一个点,那么序列会变成形如(RBRBRB)这样子的。

很自然的贪心先从中间染色,这样就可以把这个点两边的区间合成一个。特判一下两边就可以了。


Code:

#include <cstdio>
#include <cstring>
const int N=1e5+10;
int n,m,T;
char op[N],s[N];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s%s",s+1,op+1);
        n=strlen(s+1),m=strlen(op+1);
        int las=s[1]=='R',re=0,bl=0;
        for(int i=2;i<=n;i++)
            if(las!=(s[i]=='R'))
                re=re+las,bl=bl+(!las),las=(s[i]=='R');
        re=re+las,bl=bl+(!las);
        for(int i=m;i;i--)
        {
            if(op[i]=='F')//染红
            {
                --re;
                if(bl>=2) --bl;
            }
            else
            {
                --bl;
                if(re>=2) --re;
            }
        }
        if(re<=0&&bl<=0) puts("Yes");
        else puts("No");
    }
    return 0;
}

2018.11.4

原文地址:https://www.cnblogs.com/butterflydew/p/9904349.html