题目链接:“科林明伦杯”哈尔滨理工大学暑假训练赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ
题目描述
格雷福斯因为由于不知名力量失去了战斗力,需要启明小朋友为他点烟才能恢复力量,格雷福斯需要的烟是一种名为寂寞如雪的烟,启明小朋友需要截取一段连续的寂寞制作成寂寞如雪帮助格雷福斯恢复力量。
寂寞可以看做一段连续的01字符串,其中0表示落寞,1表示孤独,格雷福斯只需要孤独不需要落寞。因为格雷福斯只有两发子弹,所以格雷福斯不喜欢偶数。多个连续出现的孤独可以看做一段孤独,寂寞如雪中第奇数段长度为n的孤独可以为格雷福斯提供n2点力量,第偶数段长度为n的孤独会减少格雷福斯n2点力量,启明小朋友不知道格雷福斯最多可以恢复多少点力量,所以向你求助。
输入描述:
输入共一行,一个长度不超过1e6的字符串。
输出描述:
一个整数,最多可以恢复的力量。
示例1
输入
复制111011001111100111
111011001111100111
输出
复制30
30
说明
截取1110110011111,获得的力量为32-22+52=30
备注:
连续的1在计算时会被算成一段,不可以拆成多段
第奇数段还是第偶数段是看截取后字符串中的位置
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 6;
char a[N];
int b[N];
signed main()
{
cin >> a;
int mx, f = 0, k = 1, ans1 = 0, ans2 = 0;
for(int i = 0; i < strlen(a); i++)
{
if(a[i] == '1') b[k]++, f = 1;
if(a[i] == '0' && f) k++, f = 0; //f=0说明连续的1断掉了
}
for(int i = 1; i <= k; i++)
{
if(i & 1)
{
ans1 = max(ans1 - b[i] * b[i], 0ll); //从偶数开始取
ans2 = max(ans2 + b[i] * b[i], 0ll); //从奇数开始取
}
else
{
ans1 = max(ans1 + b[i] * b[i], 0ll);
ans2 = max(ans2 - b[i] * b[i], 0ll);
}
mx = max(mx, max(ans1, ans2));
}
cout << mx;
return 0;
}