分析
本题题意为求一串01数字中,每个0距离最近的1的距离之和。
做法1
统计出连续0个数的数组,若有n个连续0:1、首尾的连续0,则distance_sum=(n+1)n/2;2、中间的连续0,则distance_sum=2((n/2+1)*n/2/2),如果n为奇数还要再加上n/2+1。
#include<bits/stdc++.h>
using namespace std;
#define int long long
signed main()
{
int t,n;
scanf("%lld",&t);
for(int p=1;p<=t;p++)
{
vector<int> k;
int b,startwith0=0,endwith0=0,cnt0=0;
char c;
printf("Case #%lld: ",p);
scanf("%lld",&n);
getchar();
for(int i=0;i<n;i++)
{
c=getchar();
b=c-'0';
if(!i&&!b)startwith0=1;
if(i==n-1&&!b)endwith0=1;
if(!b)cnt0++;
else
{
k.push_back(cnt0);
cnt0=0;
}
}
k.push_back(cnt0);
int l=k.size(),start=0,end=l-1;
long long ans=0;
if(startwith0)
{
ans+=(k[0]+1)*k[0]/2;
start=1;
}
if(endwith0)
{
ans+=(k[l-1]+1)*k[l-1]/2;
end=l-2;
}
for(int i=start;i<=end;i++)
{
if(k[i]%2)
{
ans+=2*((k[i]/2+1)*(k[i]/2)/2)+k[i]/2+1;
}
else
{
ans+=2*((k[i]/2+1)*(k[i]/2)/2);
}
}
printf("%lld\n",ans);
}
return 0;
}
做法2
从前往后扫一遍,得到每个0距离左边1的最近距离;再从后往前扫一遍,得到每个0距离右边1的最近距离;然后两个数组比较取其大相加即可。