接过队友的锅敲这道题,结果没太想清楚着急直接敲调试了好久。。又被队友嫌弃。。真心为我的代码能力担忧。。
“不要头脑一热就开始写”
下来检查发现当时的代码都写错了。。话说区域赛的数据为何这么弱。。
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=5583
题意:
给定01串,连续的相同字符的长度的记为距离。改变一个字符,使得最后的距离平方和最大。
分析:
对于每个元素记一个连续的前缀长度,一个连续的后缀长度,然后O(n)枚举一下就好了。
比赛的时候最后计算那里加加减减搞得很烦,实际化简一下就很好算了。
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 5, INF = 0x3f3f3f3f;
int a[maxn],f[2][maxn], f1[2][maxn];
char s[maxn];
bool flg[maxn];
int b[maxn];
int main (void)
{
int t;scanf("%d",&t);
for(int tt = 1; tt <= t; tt++){
scanf("%s",s);
int slen = strlen(s);
ll lian = 0;
ll yuan = 0;
memset(flg, true, sizeof(flg));
memset(f, 0 ,sizeof(f));
memset(f1, 0 ,sizeof(f1));
memset(b, 0 ,sizeof(b));
for(int i = 0; i < slen; i++){
a[i] = s[i]-'0';
}
for(int i = 0; i < slen; i++){
if(i < slen - 1 && a[i] != a[i + 1]){
flg[i] = false;
flg[i +1] =false;
}
if(i == 0 || a[i] == a[i - 1]) lian++;
else{
yuan += lian * lian;
lian = 1;
}
}
yuan += lian * lian;
for(int i=0;i<slen;i++){
f[a[i - 1]][i] = b[a[i - 1]];
b[!a[i]] = 0;
b[a[i]]++;
}
memset(b, 0 ,sizeof(b));
for(int i = slen - 1; i >= 0; i--){
f1[a[i + 1]][i] = b[a[i + 1]];
b[!a[i]] = 0;
b[a[i]]++;
}
ll aans = yuan;
ll res;
for(int i= 0;i < slen; i++){
if(flg[i]) continue;
if(a[i - 1] != a[i + 1]){
if(a[i] == a[i + 1] || i == slen - 1)
res = yuan + 2 * f[a[i - 1]][i] - 2 * f1[a[i + 1]][i];
else if(a[i] == a[i - 1] || i == 0)
res = yuan - 2 * f[a[i - 1]][i] + 2 * f1[a[i + 1]][i];
}else res = yuan + 2 * f[a[i - 1]][i] + 2 * f1[a[i + 1]][i] + 2ll * f[a[i - 1]][i] * f1[a[i + 1]][i];
aans = max(aans, res);
}
printf("Case #%d: %lld
", tt, aans);
}
return 0;
}