Description
985有一个长度为n的0-1串,已知他最多可以修改k次(每次修改一个字符即0->1 或者 1->0),他想知道连续的全1子串最长是多少。
Input
第一行输入一个整数t,代表有t组测试数据。
每组数据第一行输入两个整数n,k分别代笔上面的信息。
注:1 <= t <= 12,1 <= n <= 100000,0 <= k <= 100000。
Output
一个整数代表可以得到的最大长度。
Sample Input
2
6 3
010100
6 2
010100
Sample Output
5
4
HINT
这道题应该使用尺取法写的,不过用二分也能写。 最长的纯1串肯定是从一个数开始的(好像是废话),所以定义状态dp[i] 以 i 元素开始的最长纯1串。
代码解释的比较详细:
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define N 200000
using namespace std;
typedef long long ll;
int arr[N],dp[N],id[N],num[N];
char str[N];
int erfen(const int *num,int l,int r,int k);
int main()
{
int t,n,i,j,k;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
memset(num,0,sizeof(id));
scanf("%d%d",&n,&k);
scanf(" %s",str+1);
for(i=1; i<=n; i++)
arr[i] = str[i] - '0';
int tail = 0,head = 0;
for(i=1; i<=n; i++)
{
num[i] = num[i-1];
if(arr[i] == 0)
num[i] += 1;
} //num数组统计前i个元素含有 0 的个数。
int maxx = 0;
for(i=1; i<=n; i++)
{
dp[i] = erfen(num,i,n,k); //二分从i点可以延伸的最大长度
// printf("%d ",dp[i]);
if(dp[i] > maxx)
maxx = dp[i];
}
printf("%d\n",maxx);
}
return 0;
}
int erfen(const int *num,int l,int r,int k)
{
int l2 = l;
if(num[r] - num[l-1] <= k)
return r-l+1;//r-l+1;
int mid = (r+l)/2;
while(1)
{
if(num[mid]-num[l2-1] == k)
{
int j = mid;
while(num[j] == num[mid])
{
j += 1;
}
return j-l2;
}
else if(num[mid]-num[l2-1] > k)
r = mid-1;
else
l = mid+1;
mid = (r+l)/2;
}
}
这道题是66ms过的,而尺取法是20ms左右,尺取法还是快一点,我把尺取法的代码也放在这里好了。
#include <stdio.h>
#include <string.h>
#define N 1000000+100
int arr[N];
char str[N];
int max(int a,int b)
{
if(a >= b)
return a;
return b;
}
int main()
{
int t,n,i,k;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
scanf(" %s",str+1);
for(i=1; i<=n; i++)
{
arr[i] = str[i] - '0';
}
int tail = 0,head = 0;
for(i=1; i<=n; i++)
{
if(arr[i]==0 && --k<0)
break;
++tail;
}
arr[n+1] = 0;
while(arr[tail+1] == 1)
tail++;
int maxx = tail;
if(tail >= 1)
head = 1;
for(tail; tail<n; )
{
if(arr[tail+1] == 1)
tail++;
else
{
while(arr[head] != 0)
head += 1;
head++; tail++;
}
maxx = max(tail-head+1,maxx);
}
printf("%d\n",maxx);
}
return 0;
}