题解:P10608 双人游戏

· · 题解

前言

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

思路

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

那么我们可以把每个 s_{x_i} 设为 c_i,对于一个 s_{i}

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

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

可是我们发现还有一个边界:n=m(即整个棋盘都是空的),此时我们发现第一轮下 \tt W\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:修改了一些笔误。