题意:
在黑与白的王国(KBW),有两种:黑色和白色的青蛙青蛙青蛙。
现在,青蛙站在一条直线上,其中一些是黑色的,其他的都是白色的。这些青蛙的总强度是通过将线划分成最小的部分,每个部分都应该是连续的,并且只能包含一种青蛙。强度是每一部分的平方的总和。
然而,一个古老的邪恶的女巫来了,告诉青蛙,她将改变颜色的大多数一只青蛙,从而这些青蛙的力量可能改变。
青蛙想知道女巫完成了她的工作后,最大的力量是可以的。
#include<bits/stdc++.h>
using namespace std;
//思想:遍历每个连接点,既连个部分之间的点,假设遍历到i,如果l[i-1]==1&&i!=1的话,那么合并i i-1 i-2 ,合并i-2的前提是i-2>=0
//如果l[i-1]!=1 那么选取l[i-1]和l[i]中的最大值,最大值增加1,最小值减少1,然后求和
char a[100005];
long long bf[100005][2]; //记录每一部分断点 这分代码没用这个,我就不改了。
long long l[100005]; //每一部分的长度
long long ans[100005];//每一部分的平方
int main()
{
long long t;
scanf("%lld",&t);
getchar();
long long ca=0;
while(t--)
{
ca++;
scanf("%s",a);
memset(bf,-1,sizeof(bf));
memset(ans,0,sizeof(ans));
long long all=0;
long long i;
long long ml;
for(i=0; a[i]!='\0'; i++)
{
if(i==0)
{
bf[all][0]=0;
}
else
{
if(a[i]==a[i-1])
{
bf[all][1]++;
}
else
{
bf[all][1]=i-1;
l[all]=bf[all][1]-bf[all][0]+1; //记录部分长度
if(all==0)
ml=0;
else
{
if(l[all]>l[ml])
{
ml=all;
}
}
all++;
bf[all][0]=i;
}
}
}
bf[all][1]=i-1;
l[all]=bf[all][1]-bf[all][0]+1;
if(l[all]>l[ml])
ml=all;
/*prlong longf("%d\n",ml);
for(long long i=0; i<=all; i++)
{
prlong longf("%d %d %d\n",bf[i][0],bf[i][1],l[i]);
}*/
long long sum=0; //不改变青蛙前的平方和
for(long long i=0;i<=all;i++) //部分平方和计算
{
ans[i]=l[i]*l[i];
sum+=ans[i];
}
long long an=sum;
for(long long i=1;i<=all;i++)
{
long long tsum=sum;
if(l[i-1]==1&&i!=1) //如果l[i-1]==1&&i!=1的话,那么合并i i-1 i-2 ,合并i-2的前提是i-2>=0
{
if(i-2>=0)
tsum-=ans[i-2];
tsum-=(ans[i]+ans[i-1]);
if(i-2<0)
tsum+=(l[i-1]+l[i])*(l[i-1]+l[i]);
else
tsum+=(l[i-1]+l[i]+l[i-2])*(l[i-1]+l[i]+l[i-2]);
if(tsum>an)
an=tsum;
}
else//如果l[i-1]!=1 那么选取l[i-1]和l[i]中的最大值,最大值增加1,最小值减少1,然后求和
{
long long t;//大值
long long d;//小值
if(l[i-1]>l[i]) //选取大值和小值
{
t=i-1;
d=i;
}
else
{
t=i;
d=i-1;
}
tsum-=(ans[i]+ans[i-1]);//减去这两部分的原先平方和
tsum+=(l[t]+1)*(l[t]+1)+(l[d]-1)*(l[d]-1);//更新
if(tsum>an)
an=tsum;
}
}
printf("Case #%lld: %lld\n",ca,an);
}
}