题目链接:点击打开链接
给出一个由01构成字符串, 可以修改字符一次, 问连续的0或1最大的平方和是多少.
题目即求最长的0串或者1串, 先求出给出字符串的平方和, 遍历一次, 分两种情况, 一种是当前为1, 一种是一般情况. 当前为1时, 要判断
前一段与后一段和是否大于最大. 求出最多增长加到ans即可.
AC代码:
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
#include "stack"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
#include "string"
#include "cstdlib"
using namespace std;
typedef long long ll;
#define X first
#define Y second
#define exp 1e-8
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 5;
int t;
char s[MAXN];
std::vector<ll> v;
std::map<ll, ll> mp;
int main(int argc, char const *argv[])
{
for(ll i = 0; i <= 1e5 + 5; ++i)
mp[i] = i * i;
scanf("%d", &t);
for(int cas = 1; cas <= t; ++cas) {
v.clear();
scanf("%s", s);
int len = strlen(s), num0 = 0, num1 = 0;
for(int i = 0; i < len; ++i) {
if(s[i] == '0') {
num0++;
if(num1 != 0) {
v.push_back(num1);
num1 = 0;
}
}
else {
num1++;
if(num0 != 0) {
v.push_back(num0);
num0 = 0;
}
}
}
if(num0 != 0) v.push_back(num0);
else v.push_back(num1);
int size = v.size();
ll ans = 0, res = 0, r = 0;
for(int i = 0; i < size; ++i)
ans += mp[v[i]];
for(int i = 1; i < size; ++i) {
ll x = max(v[i], v[i - 1]), y = min(v[i], v[i - 1]);
if(v[i] == 1 && i < size - 1) r = 2 * v[i - 1] * v[i + 1] + 2 * v[i - 1] + 2 * v[i + 1];
else r = 2 * x - 2 * y + 2;
res = max(res, r);
}
printf("Case #%d: %lld\n", cas, ans + res);
}
return 0;
}