[luoguP10608]双人游戏
题目信息
原题链接
来源:[LGR-190]2024洛谷6月月赛II Div1 T1/Div2 T3
题意
长度为的序列,其中只包含B
,W
和个_
。给定长度为的序列,表示玩家小需要将修改为B
或W
,且对小R和小M公开。
小R希望极长同色连续段数(定义见原题)尽可能多,小M希望极长同色连续段数尽可能少,求经过序列的操作后,极长同色连续段数的数量
赛时
Subtask害人不浅
在经历成功切下后,蒟蒻开始思考
由于序列对双方公开,所以对双方来说,即使需要按照的顺序来操作,双方的操作也可以视为无序,因此我们可以将直接填入中。
假设中只有没有操作,若,则可能存在三种情况
- ,此时选择与和相反的字符填入
- ,此时选择与或相反的字符填入均可
- 或,此时选择与相邻字符的相反的字符填入即可
综上,我们发现,对于小R来说,选择与相邻字符相反的字符就是最优答案
同理,对小M来说,选择与相邻字符相反的字符就是最优答案
后来蒟蒻因为造出了的hack数据,导致以为自己操作无序的结论证假,当场10pts跑路
赛后
事实上,操作无序的结论是正确的,只是因为蒟蒻没有深入考虑的情况。
当时,由于小不管将修改为什么,都不会影响输出的结果,因此,只需要将任意修改为B
或W
即可
同时,也有可能出现__________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:喜报,上洛谷了
分类:
题解 / 2024赛时
标签:
基础算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~