• [牛客网] 染色【思维题,模拟】


    Online Judge牛客网NOIP2018赛前集训营-提高组(第八场)T1

    Label:思维题,模拟

    ps:这套题目由于被改成模拟离线赛,所以下面的题目描述改编了,题目还是一样的。


    题目描述

    众所周知,Sheldon是一个领地意识极强的人。

    最近Leonard和Sheldon一起买了一张新沙发,这个沙发很长,上面一共有nn个坐垫,也就是说只有nn个位置,而且每个位置上只能做一个人。在Sheldon在慎重挑选后,他找了一个位置,并向Leonard提出要长期占有这个位置。

    终于,Leonard无法再忍受Sheldon对沙发座位的无理要求,要和Sheldon争夺沙发座位!!

    Leonard会挑选若干个连续的位置(可以是零个)并占领它们。Sheldon当然不会示弱,他也像Sheldon一样挑选若干个连续的位置(可以是零个)并占领它们。这时Leonard也不乐意了,于是又占领了一些位置。Sheldon又不高兴了。。。。。。

    最后两人都累了,由于刚才过于激动,所以忘记了自己曾经占领过什么位置,只记得自己最后占领了什么位置(一个位置可能在被Leonard占领后又被Sheldon气愤的占领,而且任何时候一个位置都只能被至多一个人占领)。很巧的是,所有的位置最后都被占领了。由于中途Leonard和Sheldon可能会去上厕所,所以两人并不是交替占领位置的,而可能有人会连续两次占位置。

    在一旁的Penny却默默记住了两个人占领的时间顺序,由于Penny对自己的记忆力有所怀疑,所以找来了老X来确定一下自己所记下的顺序是否是对的。简单地说就是让老X确定一下是否存在某种占领方案使得占领到最后跟Leonard与Sheldon的“领地”符合。

    输入

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

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

    第二行是一个由FL组成的字符串t表示m次操作,F表示某次是Sheldon操作,L表示是Leonard操作,同时字符串的长度为m。

    输出

    对每组测试点输出一行,如果满足条件输出Yes否则输出No。

    样例

    Input

    3
    R
    FL
    RRRBR
    FFFF
    BRRBBRB
    LFL
    

    Output

    Yes
    No
    Yes
    

    Hint

    100%的数据满足(n,m≤100000)

    所有数据满足(T≤20)

    题解

    正着按时间轴来模拟情况会很复杂,尝试看样例找规律也没什么发现,不太可做。

    但是发现,最后留下的颜色一定是那一段的最后一笔(废话)。我们尝试倒序逆着时间轴模拟操作,相应的,填涂颜色变成消除颜色,为什么这两者等价呢。看下面的例子:

    逆序时:在第t秒,我们删除中间这一段R

    第t秒:([][][][]BBBRRBBB[][][])

    第t-1秒:([][][][]BBB[][]BBB[][][])

    正序时:在第t-1秒,我们将一段R覆盖在B

    第t-1秒:([][][][]BBBBBBBB[][][])

    第t秒:([][][][]BBBRRBBB[][][])

    相比之下,第t-1秒的情况,只是逆序去做时:中间空了一段,正序做时:中间是连接着的。但是两者其实没有差别。因为逆序操作时,中间那一段不可能再被填上颜色,所以我们可以将两端的B合并了,而这也就相当于正序时的那一段。

    做法就出来了,只要模拟这个过程就好了。当然模拟并不需要真的用双向链表之类的东西去维护,我们一开始记录一个(cntb,cntr)即可,表示初始时L的块数R的块数。然后从后往前根据题目给的操作序列来消除一整块。

    注意一点,最后判的时候是(cntb<=0)&&(cntr<=0),取≤是因为中间操作时可以选择不涂色。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int main(){
    	int T;scanf("%d",&T);
    	while(T--){
    		char a[N],op[N];
    		scanf("%s",a+1);scanf("%s",op+1);
    		int len=strlen(a+1),round=strlen(op+1);
    		int cntr=0,cntb=0;
    		for(int i=1;i<=len;i++)if(a[i]!=a[i-1]){
    			if(a[i]=='R')cntr++;
    			else cntb++;
    		}
    		for(int i=round;i>=1;i--){
    			if(op[i]=='L'){
    				cntb--;if(cntr>=2)cntr--;
    			}
    			else{
    				cntr--;if(cntb>=2)cntb--;
    			}
    		}
    		if(cntb<=0&&cntr<=0)puts("Yes");
    		else puts("No");
    	}
    }
    
  • 相关阅读:
    QA问答系统,QA匹配论文学习笔记
    HMM Viterbi算法 详解
    py2 to py3 return iterator
    git 的回退
    mysql之group_concat函数详解
    sqlserver系统表使用
    Spring事务配置的五种方式
    MySQL 触发器简单实例
    64位Java开发平台的选择,如何区分JDK,Tomcat,eclipse的32位与64版本
    HSSFWorkbook和XSSFWorkbook的区别
  • 原文地址:https://www.cnblogs.com/Tieechal/p/11487846.html
Copyright © 2020-2023  润新知