CodeForce-CF873B-Balanced Substring
Abstract
传送门
本题定义平衡串为 0 和 1 数量相等的字符串,要求我们找出给定 01 串中含有的最大平衡串。
Idea
如果把 1 视为 +1 ,0视为 -1,那么一个 01 串是平衡串当且仅当其和值为 0 ,那么问题就转变为寻找给定 01 串中和值为 0 的最长子段。
首先做一个前缀和,a[i] 表示前 i 项的和值,那么对于区间 [l,r] ,只要 a[r] - a[l-1] == 0,它就是一个平衡串,暴力枚举 l 和 r ,时间复杂度是 O(n^2),显然超时。实际上,对于每一个 a[i] ,我们只希望找到一个 a[j] ,使得 a[i] == a[j] ,那么我们可以考虑存储 a[i] 出现的最大序号和最小序号,然后取其差值即可得到答案,细节见代码。
Code
#include <bits/stdc++.h>
using namespace std;
// buyy
int a[300000];
int mint[300000];
int maxt[300000];
int main()
{
int n;
memset(mint, 0x3f3f3f3f, sizeof mint);
memset(maxt, -0x3f3f3f3f, sizeof maxt);
scanf("%d\n", &n);
int sum = 0;
int ans = 0;
for (int i = 1; i < n + 1; i++)
{
char c = getchar();
if (c == '1')
{
sum++;
}
else
{
sum--;
}
if (sum > 0)
{
mint[sum] = min(mint[sum], i);
maxt[sum] = max(maxt[sum], i);
}
else if (sum == 0)
{
ans = i;
}
else
{
int p = -sum + n;
mint[p] = min(mint[p], i);
maxt[p] = max(maxt[p], i);
}
a[i] = sum;
}
for (int i = 1; i <= n; i++)
{
if (a[i] == 0)
{
continue;
}
if (a[i] < 0)
{
a[i] = -a[i] + n;
}
ans = max(ans, maxt[a[i]] - mint[a[i]]);
}
cout << ans;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现