[luoguP10608]双人游戏

题目信息

原题链接
来源:[LGR-190]2024洛谷6月月赛II Div1 T1/Div2 T3

题意

长度为\(n\)的序列\(s\),其中只包含BW\(m\)_。给定长度为\(m\)的序列\(O=[\lang c_1,x_1\rang, \lang c_2,x_2\rang, \cdots,\lang c_m,x_m\rang](c_i\in\{\mathtt{R}, \mathtt{M}\},s_{x_i}=\text{'_'})\),表示玩家小\(c_i\)需要将\(s_{x_i}\)修改为BW,且\(O\)对小R和小M公开。
小R希望极长同色连续段数(定义见原题)尽可能多,小M希望极长同色连续段数尽可能少,求经过序列\(O\)的操作后,极长同色连续段数的数量

赛时

Subtask害人不浅
image
在经历\(1.5h\)成功切下\(B2\)后,蒟蒻开始思考\(C\)
由于序列\(O\)对双方公开,所以对双方来说,即使需要按照\(O\)的顺序来操作,双方的操作也可以视为无序,因此我们可以将\(c_i\)直接填入\(s\)中。
假设\(O\)中只有\(\lang c_m,x_m \rang\)没有操作,若\(c_m=\text{R}\),则可能存在三种情况

  1. \(s_{x_i - 1} = s_{x_i + 1}\),此时选择与\(s_{x_i - 1}\)\(s_{x_i + 1}\)相反的字符填入
  2. \(s_{x_i - 1} \ne s_{x_i + 1}\),此时选择与\(s_{x_i - 1}\)\(s_{x_i + 1}\)相反的字符填入均可
  3. \(x_i = 1\)\(x_i = n\),此时选择与\(s_{x_i}\)相邻字符的相反的字符填入即可

综上,我们发现,对于小R来说,选择与相邻字符相反的字符就是最优答案
同理,对小M来说,选择与相邻字符相反的字符就是最优答案

后来蒟蒻因为造出了\(m=n\)的hack数据,导致以为自己操作无序的结论证假,当场10pts跑路

赛后

事实上,操作无序的结论是正确的,只是因为蒟蒻没有深入考虑\(m=n\)的情况。
\(m=n\)时,由于小\(c_1\)不管将\(s_{x_1}\)修改为什么,都不会影响输出的结果,因此,只需要将\(s_{x_1}\)任意修改为BW即可
同时,也有可能出现__________B的情况,此时,只需要从后向前再次扫描即可解决

代码

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int N = 200005;

char g[N];
int n, m;

char inv(char c){
    return c == 'B' ? 'W' : 'B';
}

bool valid(char c){
    return c == 'B' || c == 'W';
}

int main(){
    scanf("%d%d", &n, &m);
    scanf("%s", g + 1);
    while (m -- ) {
        char op[2];
        int x;
        scanf("%s%d", op, &x);
        g[x] = *op;
        if (m == n - 1) g[x] = 'B';
    }

    for (int i = 2; i <= n; i ++ ){
        if (g[i] == 'B' || g[i] == 'W') continue;
        if (g[i] == 'M' && valid(g[i - 1])) g[i] = g[i - 1];
        else if (g[i] == 'R' && valid(g[i - 1])) g[i] = inv(g[i - 1]);
    }
    
    for (int i = n - 1; i; i -- ){
        if (g[i] == 'B' || g[i] == 'W') continue;
        if (g[i] == 'M' && valid(g[i + 1])) g[i] = g[i + 1];
        else if (g[i] == 'R' && valid(g[i + 1])) g[i] = inv(g[i + 1]);
    }

    int ans = 0;
    for (int i = 1; i <= n; i ++ )
        if (g[i] != g[i - 1]) ans ++ ;

    printf("%d\n", ans);

    return 0;
}

UPDATE

2024.6.26:喜报,上洛谷

posted @ 2024-06-21 10:38  是一只小蒟蒻呀  阅读(18)  评论(0编辑  收藏  举报