Codeforces --Social Distance(模拟)

在这里插入图片描述
在这里插入图片描述

思路:

我们可以分成三种情况
1.0~1或1~0的区间
  第一个0到第一个1之间的0可以放多少个1,考虑到第一个1之前的k位不能放1,那么这段区间(假设这段区间有dis个0)最多应该可以放 ( d i s − k ) / ( k + 1 ) (dis-k)/(k+1) (disk)/(k+1)个1
  反过来1~0的区间同理
2.1~1的区间
  每位1附近的k位都不能放1,每连续k个0可以放置一个1,那么还剩 d i s − k dis-k disk位可以放1,也就是可以放 ( d i s − k ) / ( k + 1 ) (dis-k)/(k+1) (disk)/(k+1)个1
3.0~0的区间(全0的情况)
  假设全0的情况,我们可以通过把0~0的区间变成1~1的区间,左右补零实现。如下图:
[在这里插入图片描述
最后可以得到全0的情况下,可以放置 n + k k + 1 \frac{n+k}{k+1} k+1n+k个1

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
ll n,k,t,cnt1,b[maxn],ans;
char a[maxn];
int main(){
	cin>>t;
	while(t--){
		cin>>n>>k;
		for(int i=1;i<=n;i++) cin>>a[i];
		cnt1=0;
		for(int i=1;i<=n;i++){
			if(a[i]=='1') b[++cnt1]=i;
		}
		if(cnt1==0) cout<<(n+k)/(k+1)<<endl;
		else{
			ans=(b[1]-1)/(k+1)+(n-b[cnt1])/(k+1);
			for(int i=1;i<cnt1;i++){
				ans+=(b[i+1]-b[i]-1-k)/(k+1);
			}
			cout<<ans<<endl;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值