1 条题解

  • 0
    @ 2025-8-24 22:59:37

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar O_v_O
    replay

    搬运于2025-08-24 22:59:37,当前版本为作者最后更新于2024-06-16 22:42:29,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    前言

    我赛时傻了,想到这个解法后自我否定掉了,痛失前 3030 名,大家引以为戒。

    思路

    首先很显然各自都知道对方的操作,那么就相当于操作的先后没用。

    那么我们可以把每个 sxis_{x_i} 设为 cic_i,对于一个 sis_{i}

    • 如果它是 W\tt WB\tt B,那么啥都不用做;
    • 如果它是 R\tt R,因为小 R 是想让极长同色连续段数尽量多,所以他肯定会染与 si1s_{i-1} 相反的颜色;
    • 如果它是 M\tt M,因为小 M 是想让极长同色连续段数尽量少,所以他肯定会染与 si1s_{i-1} 相同的颜色;

    但是我们注意到如果这样搞,在前面有一连串空棋盘时,前面都没法被进行有效操作。

    那么很明显我们可以再倒着来一遍就行了啊,这样前面的空棋盘也能被处理到。

    可是我们发现还有一个边界:n=mn=m(即整个棋盘都是空的),此时我们发现第一轮下 W\tt WB\tt B 是等价的,那么我们只用随便下一个就行了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N=2e5+5;
    int n,m,ans;
    string s;
    char c;
    int k;
    
    signed main(){
    	ios::sync_with_stdio(0);
    	cin.tie(nullptr);
    	cin>>n>>m>>s;s=' '+s;
    	for(int i=1;i<=m;i++){
    		cin>>c>>k;
    		if(m==n&&i==1) s[k]='W';
    		else s[k]=c;
    	}
    	for(int i=1;i<=n;i++){
    		if(s[i]=='R'){
    			if(s[i-1]=='B') s[i]='W';
    			if(s[i-1]=='W') s[i]='B';
    		}
    		if(s[i]=='M'){
    			if(s[i-1]=='B') s[i]='B';
    			if(s[i-1]=='W') s[i]='W';
    		}
    	}
    	for(int i=n;i>=1;i--){
    		if(s[i]=='R'){
    			if(s[i+1]=='B') s[i]='W';
    			if(s[i+1]=='W') s[i]='B';
    		}
    		if(s[i]=='M'){
    			if(s[i+1]=='B') s[i]='B';
    			if(s[i+1]=='W') s[i]='W';
    		}
    	}
    	for(int i=1;i<=n;i++){
    		if(s[i]!=s[i-1]) ans++;
    	}
    	cout<<ans;
    	return 0;
    }
    

    upd:修改了一些笔误。

    • 1

    信息

    ID
    10277
    时间
    1000ms
    内存
    512MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者