题目简述:输入两个整数n和k, 分别代表由01组成的二进制字符串的长度和任意两个1之间的距离;模拟餐厅中两个人的最短距离;给出01字符串,求出最多能再插入多少个1?
例如:n=6,k=1 100010 最多还能在2号位上插入1
解决思路:找出01字符串中所有的0区域(即任意相邻两个1之间)区域分三种情况
①0区域位于开头,其右端存在1; 将0区域的长len-k (即减去右侧与1相邻的k个数)得到独立的00串的长度
②0区域位于中间,其两端均存在1;将0区域的长len-2*k,得到独立的00串的长
③0区域位于末端,其左端存在1;将0区域的长len-k,得到独立的00串
即:0区域左侧有1减k,右侧有1再减k,都有减2k,没有不减
//1367C-Social Distance
#include<iostream>
#include<cmath>
#include<string>
using namespace std;int main(){
int t;
cin>>t;
for(int test=1;test<=t;test++){
int n,k;
cin>>n>>k;
string s;
cin>>s;
int res=0;
for(int i=0;i<n;){
int j=i+1;
for(;j<n&&s[j]!='1';j++); // 求出前两个1或者第一个1的位置,即100...01的情况的000...1的情况
int left=s[i]=='1'?k:0; //left和right作为标志,0区域左右两侧是否存在1
int right=j<n&&s[j]=='1'?k:0; //顺便储存k的值,所以要么是0,要么是k
int len=j-i; //求出ij之间的距离+1,可能的连续0区域的长len
if(left==k){ //由于s[0]可能是1 ,所以len--;
len--;
}
len-=left+right; //用len-左边可能的k和右边可能的k
if(len>0){
res+=ceil(len*1.0/(k+1)); //len*1.0/(k+1)向上取整,注意✖1.0的作用
} //此处官方答案 (len+k)/(k+1)与上面效果一样
i=j;
}
cout<<res<<endl;
}
return 0;
}