原本的思路是就是枚举,但一直不敢动,因为硬肝应该会超时,而且代码也比较难打,但想来想去又没什么法子。后来去看了同校的大佬的代码,才发现可以用队列来维护,这样不仅容易打代码,而且时间复杂度也变成了2*n。
代码如下:
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int MM=1e5+20;
char s[MM];
int a[MM];
queue<int> q0,q1;
int main()
{
int i,j,T,n,m,t;
scanf("%d",&T);
while (T--)
{
while (!q0.empty()) q0.pop();
while (!q1.empty()) q1.pop();
int len=0,max=0,ans=0,cnt=0,ans2=0;
scanf("%d%d",&n,&m);
scanf("%s",s+1);
for(i=1;i<=n;i++) // 0
{
if(s[i]=='0')
{
len++;
q0.push(0);
}
else if(cnt<m)
{
q0.push(1);
len++;
cnt++;
}
else
{
q0.push(1);
if(len>max) max=len;
while (q0.front()!=1&&!q0.empty())
{
len--;
q0.pop();
}
q0.pop();
while(q0.front()!=0&&!q0.empty())
{
len--;
cnt--;
q0.pop();
}
}
if(len>max)
max=len;
}
ans=max;
if(ans>n)
ans=n;
len=max=cnt=0;
for(i=1;i<=n;i++) // 1
{
if(s[i]=='1')
{
q1.push(1);
len++;
}
else if(cnt<m)
{
cnt++;len++;
q1.push(0);
}
else
{
q1.push(0);
if(len>max) max=len;
while (q1.front()!=0&&!q1.empty())
{
q1.pop();
len--;
}
q1.pop();
while(q1.front()!=1&&!q1.empty())
{
len--;
cnt--;
q1.pop();
}
}
if(len>max)
max=len;
}
if(max>ans) ans=max;
if(ans>n) ans=n;
printf("%d\n",ans);
}
return 0;
}