暑期训练day8 Social Distance

一.题意

Polycarp和他的朋友想参观一家新餐馆。这家餐厅有n张桌子,沿直线排列。人们已经坐在一些桌子旁了。表格按从左到右的顺序从1到n编号。餐厅的状态由一个长度为n的字符串来描述,该字符串包含字符“1”(位置被占用)和“0”(位置为空)。

餐厅的规定禁止人们坐在距离k或更少的地方。也就是说,如果一个人坐在数字i的桌子旁,那么所有数字来自i−k到i+k(第i个除外)应该是空闲的。换句话说,任意两个被占用桌子的绝对数差必须严格大于k。

例如,如果n=8和k=2,则:

字符串“10010001”、“10000010”、“00000000”、“00100000”满足餐厅规则;

字符串“10100100”、“10011001”、“11111111”不符合餐厅的规则,因为每个字符串都有一对距离小于或等于k=2的“1”。

特别地,如果餐厅的状态是由不带“1”的字符串或带一个“1”的字符串描述的,则满足餐厅的要求。

您将得到一个描述餐厅当前状态的二进制字符串s。我们保证这家餐厅的规章制度能得到满足。

找出你能占用的免费餐桌的最大数量,以免违反餐厅的规定。从形式上讲,可以用“1”替换的“0”的最大数目是多少,以便仍然满足要求?

例如,如果n=6,k=1,s=“100010”,那么问题的答案是1,因为只有第3位的位置可以

 二.输入输出

输入

第一行包含一个整数t(1≤T≤10^4)-测试中的测试用例数。接着是t测试用例。

每个测试用例从一行开始,该行包含两个整数n和k(1≤K≤N≤2.⋅10^5)餐厅的桌子数量和两个人之间允许的最小距离。

每个测试用例的第二行包含一个长度为n的二进制字符串s,由“0”和“1”组成,这是对餐厅中空闲和占用表的描述。给定的字符串满足餐厅的规则-任意两个“1”的索引之间的差值大于k。

一个测试中所有测试用例的n之和不超过2⋅10^5

输出

对于每个测试用例,输出一个整数—您可以占用的位置数,以避免违反餐厅的规则。如果无法获取位置,那么显然,您需要输出0。

三.思路

将字符串中的0进行分块处理

0区域可能位于字符串开头,结尾,中间,

或者为全0字符串 再进行讨论。

四.上板子

#include <iostream>
#include <algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
int main()
{
    ll m;
    cin >> m;
    ll n,k;
    while (m--)
    {
        cin >> n >> k;
        string a;
        cin >> a;
		int res = 0;

		for (int i = 0; i < n;) 
		{
			int j = i + 1;

			for (; j < n && a[j] != '1'; j++);
				int left = a[i] == '1' ? k : 0;
				int right = j < n&& a[j] == '1' ? k : 0;
				int len = j - i;
			if (left == k) 
			{
				len--;
			}

			len -= left + right;

			if (len > 0)
			{
				res += (len + k) / (k + 1);
			}

			i = j;
		}

		cout << res << endl;

    }
    return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值