一天哥尔·D·文博在公厕里,忽然听到厕间有人说话,朋友,有手纸吗?
哥尔·D·文博翻了翻口袋,抱歉,没有。
过了几秒,那人又问:朋友,有小块报纸吗?
哥尔·D·文博无奈地一笑,对不起,没有,我只是来尿尿。
又过了几秒钟,厕间门缝塞出一张10元人民币,朋友,能破成10张1块的吗?
然后哥尔·D·文博给了他10个硬币!!!
硬币的作用还是蛮大的,有时候甚至可以决定你的命运,比如考试的时候,选择题很大程度上都可以取决于硬币!
<span style="color:#333333"><span style="color:#333333">在遇到不能抉择的问题时,抛硬币是最好的选择,并不是因为硬币能帮你决定什么,而是因为在硬币抛出的那一刻,答案便会出现在心里!</span></span>
<span style="color:#333333"><span style="color:#333333"> </span></span>
(临近考试,别人都忙着复习,而哥尔·D·文博早已稳操胜券,这天他来到自习室感到一阵无敌的空虚,于是从兜里掏出了n枚硬币,打算考考你)
n个硬币排成一排,你可以取走其中连续的一段硬币,但必须要求这段硬币中正面朝上的个数等于反面朝上的个数,那么你最多可以取走多少枚硬币?
输入
多组实例测试,每组输入一个01字符串(长度小于1000000),其中0表示反面朝上,1表示正面朝上
输出
对于每组数据,输出能取走的最多硬币数量,格式为 printf("Case #%d: %d\n",第几个输出,最多硬币数)
样例输入
10110
复制
样例输出
Case #1: 4
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
using namespace std;
string s;
int p[2000005];//记录前缀和第一次为某各值时字符串的长度,用key表示和映射到字符串的长度
#define mid 1000000
int main()
{
int k=0;
while(cin>>s)
{
k++;
int len=s.size();
memset(p,-1,sizeof(p));
int ans=0;
for(int i=0;i<len;i++)
{
int temp; //记录前缀和
if(s[i]=='0')
{
temp--;
}
else
{
temp++;
}
if(temp==0)//字符串从0开始到i处刚好满足条件
{
ans=max(ans,i+1);
}
else if(p[mid+temp]!=-1)//此时取其第一次达到此值到本次的中间部分即可
{
ans=max(ans,i-p[mid+temp]);
}
else
{
p[mid+temp]=i;
}
}
printf("Case #%d: %d\n",k,ans);
}
}
感慨一下,新生赛的题都不会写,哎,只能写个暴力的。
看了题解后发现一个巧妙的地方就是为了求最长序列可以另设一个映射关系从序列和映射到序列长度,由于要求最大长度所以对于此数组只用更新一次(巧妙之处)。