gym103438 L. Jason ABC(思维)
题意:
给定长为 3n 的 ABC 字符串,每次操作可选一个区间 和一个字符 ,并把区间中的字符全变成 c。求操作次数最少的方案,使 A,B,C 的出现次数相等。
思路:
如果原字符串已经合法,那么不用操作。
只需操作1次的情况:设 为 中 A 出现的次数,B 和 C 同理。假设把区间 变成 A,这就要求 且 。用双指针找是否存在这样的 。
若上述两种情况均不满足,那么一定只需操作2次,方案如下:
找最小的 p,使得 中出现次数最多的字符恰出现了 n 次,不妨设该字符为 A。这时还需要 个 B,于是把 p 右边的 个字符变成 B,再把剩下的数变成 C。
#include <bits/stdc++.h>
using namespace std;
const int N = 9e5 + 5;
int n, m, c[3][N], p;
char s[N], pi;
bool f1(char t)
{
int x = (t - 'A' + 1) % 3, y = (t - 'A' + 2) % 3;
for(int l = 1, r = 1; l <= m; l++)
{
if(r < l) r = l;
while((c[x][r]-c[x][l-1] < c[x][m]-n || c[y][r]-c[y][l-1] < c[y][m]-n)
&& r <= m) r++;
if(c[x][r]-c[x][l-1] == c[x][m]-n && c[y][r]-c[y][l-1] == c[y][m]-n)
return printf("1\n%d %d %c", l, r, t), 1;
}
return 0;
}
void f2()
{
puts("2");
int x = (pi - 'A' + 1) % 3, y = (pi - 'A' + 2) % 3;
char X = x + 'A', Y = y + 'A';
printf("%d %d %c\n", p+1, p+n-c[x][p], X);
printf("%d %d %c\n", p+n-c[x][p]+1, m, Y);
}
signed main()
{
scanf("%d%s", &n, s + 1); m = 3 * n;
for(int i = 1; i <= m; i++) {
for(int j = 0; j < 3; j++) c[j][i] = c[j][i-1];
c[s[i]-'A'][i] = c[s[i]-'A'][i-1] + 1;
if(!p && c[s[i]-'A'][i] == n) p = i, pi = s[i];
}
if(c[0][m] == c[1][m] && c[0][m] == n) return puts("0"), 0;
if(f1('A') || f1('B') || f1('C')) return 0;
f2();
return 0;
}
标签:
思维
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通