51nod-1391-01串(O(n)模拟)
2017-03-11 13:56
176 查看
1391 01串
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
给定一个01串S,求出它的一个尽可能长的子串S[i..j],满足存在一个位置i<=x <j, S[i..x]中0比1多,而S[x + 1..j]中1比0多。求满足条件的最长子串长度。
Input
Output
Input示例
Output示例
曹鹏 (题目提供者)
题解:
首先需要预处理,01串最常见的预处理就是赋值,这里也不例外,将0看作-1,将1看作1
问题便转化成了前缀和小于0的最长长度与后缀和大于0的最长长度之和。
先从前往后遍历一遍,此时前缀和假如小于零,则标记长度即可
若此时前缀和大于零,则往前找到第一个出现前缀之和+1的地方,减去即可。
这里不难证明,第一次出现的情况比为当前情况的最优解
同理 后缀也一样。
题目来源: Codility
基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
收藏
关注
给定一个01串S,求出它的一个尽可能长的子串S[i..j],满足存在一个位置i<=x <j, S[i..x]中0比1多,而S[x + 1..j]中1比0多。求满足条件的最长子串长度。
Input
一行包含一个只由0和1构成的字符串S。 S的长度不超过1000000。
Output
一行包含一个整数,表示满足要求的最长子串的长度。
Input示例
10
Output示例
0
曹鹏 (题目提供者)
题解:
首先需要预处理,01串最常见的预处理就是赋值,这里也不例外,将0看作-1,将1看作1
问题便转化成了前缀和小于0的最长长度与后缀和大于0的最长长度之和。
先从前往后遍历一遍,此时前缀和假如小于零,则标记长度即可
若此时前缀和大于零,则往前找到第一个出现前缀之和+1的地方,减去即可。
这里不难证明,第一次出现的情况比为当前情况的最优解
同理 后缀也一样。
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define maxn 1000005 char s[maxn]; int a[maxn],b[maxn],c[maxn],h[maxn]; int main() { int len,i,t=0,x,ans=0; scanf("%s",s+1); len=strlen(s+1); for(i=1;i<=len;i++) { if(s[i]=='0') a[i]=-1; else a[i]=1; } for(i=1;i<=len;i++) { t+=a[i]; if(t<0) b[i]=i; else { if(h[t+1]!=0) b[i]=i-h[t+1]; else { h[t]=i; b[i]=0; } } } t=0; memset(h,0,sizeof(h)); for(i=len;i>0;i--) { t+=a[i]; if(t>0) c[i]=len-i+1; else { if(h[-t+1]!=0) c[i]=h[-t+1]-i; else { h[-t]=i; c[i]=0; } } } for(i=1;i<=len;i++) if(b[i]>0 && c[i+1]>0) ans=max(ans,c[i+1]+b[i]); printf("%d\n",ans); }
相关文章推荐
- 51nod 1391 01串(模拟)
- 51nod 1391 01串
- 51nod 1391:01串
- 51nod 1391:01串
- 51nod 1391 01串(锻炼思维的好题)
- 51nod 1391 01串【线段树,思维】
- 51nod 1391 01串(hash+DP)
- 51nod-1391:01串
- 51nod 1391 01串 (dp+hash)
- 51nod-1391 01串
- 51nod 1391 1391 01串 (hash)
- 51nod 1391 01串
- 51NOD-1391 01串(预处理&&枚举)
- 51nod 1185 威佐夫游戏 V2 (博弈+大数乘法模拟)
- 51nod 1185 威佐夫游戏 V2 (用乘法模拟解决大数精度问题)
- 51Nod - 1432 模拟 + 贪心
- 51nod 1791 合法括号子段(模拟)
- 51Nod - 1116 枚举 + 模拟
- 【模拟】1432 独木舟【51nod】【难度:2级算法题】
- 【51nod】--1126 求递推序列的第N项 (数论&&模拟)