01串(51Nod-1391)
题目
给定一个01串S,求出它的一个尽可能长的子串S[i..j],满足存在一个位置i<=x <j, S[i..x]中0比1多,而S[x + 1..j]中1比0多。求满足条件的最长子串长度。
输入
一行包含一个只由0和1构成的字符串S。 S的长度不超过1000000。
输出
一行包含一个整数,表示满足要求的最长子串的长度。
输入样例
10
输出样例
0
思路:
通过题目可以看出,起码需要寻找两次,一次从前向后找某个位置 0 个个数大于 1 的个数的最大长度,一次从后往前找某个位置 1 的个数大于 0 的个数
由于题目中给的是 01 串,寻找满足条件的最长子串长度并不方便,因此可将 0 转为 -1,然后再去求序列的前缀和,这样一来,一段序列的和小于 0,可以说明 0 的个数大于 1,一段序列的和大于 0,可以说明 1 的个数大于 0,于是问题就转化为求到某个位置大于 0 或小于 0 的最长长度
源程序
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 1000000+5;
const int dx[] = {0,0,-1,1,-1,-1,1,1};
const int dy[] = {-1,1,0,0,-1,1,-1,1};
using namespace std;
int a[N],pos[N];
int suf[N],sum[N];
int leftPos[N],rightPos[N];
int main() {
string str;
cin>>str;
int n=str.size();
for(int i=1; i<=n; i++) {
if(str[i-1]=='0')//0转为-1
a[i]=-1;
else
a[i]=1;
sum[i]=sum[i-1]+a[i];//计算前缀和
}
memset(pos,-1,sizeof(pos));
for(int i=1; i<=n; i++) {//从前向后找
if(sum[i]<0)//记录前缀小于0的位置
leftPos[i]=i;
else {
if(pos[sum[i]+1]!=-1)
leftPos[i]=i-pos[sum[i]+1];
else {
leftPos[i]=0;
pos[sum[i]]=i;
}
}
}
memset(pos,-1,sizeof(pos));
for(int i=n; i>=1; i--) {//从后向前找
suf[i]=suf[i+1]+a[i];//计算后缀和
if(suf[i]>0)//记录后缀大于0的位置
rightPos[i]=n-i+1;
else {
if(pos[-(suf[i]-1)]!=-1)
rightPos[i]=pos[-(suf[i]-1)]-i;
else {
rightPos[i]=0;
pos[-(suf[i])]=i;
}
}
}
int res=0;
for(int i=1; i<n; i++)
if(leftPos[i]>0&&rightPos[i+1]>0)//枚举前缀大于0后缀大于0的个数
res=max(rightPos[i+1]+leftPos[i],res);//记录长度
cout<<max(0,res)<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现