Black & White(尺取)

链接:https://ac.nowcoder.com/acm/contest/893/F
来源:牛客网

* 第一行一个整数 T ,表示接下来有 T 个样例。
* 首先输入n,m,表示S串的长度n和操作次数m,其中1≤n≤1000001≤n≤100000,0≤m≤10000≤m≤1000;
* 接下来输入一个长度为n的字符串S。

输出描述:

一个整数,表示题面上描述的最大价值。
示例1

输入

复制
2
5 1
00101
2 1
01

输出

复制
4
2

说明

第一个串翻转第三个位置,00001的价值为4;第二个串翻转第一个位置,11的价值为2。
思路:记录每个串中1的位置和0的位置,然后尺取
代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
#include<cmath>

const int maxn=1e5+5;
typedef long long ll;
using namespace std;
string str;
int l[maxn];
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        cin>>str;
        l[0]=-1;
        int cnt=1;
        for(int t=0;t<n;t++)
        {
         if(str[t]=='1')
         {
           l[cnt++]=t;
         }    
        }
        l[cnt++]=n;
    //    cout<<cnt<<endl;
        if(m>=cnt-2) 
        {
        printf("%d\n",n);
        continue;
        }
        int ans=0;
        for(int t=1;t<cnt-m;t++)
        {
            ans=max(ans,l[t+m]-l[t-1]-1);
        }
        cnt=1;
        l[0]=-1;
        for(int t=0;t<n;t++)
        {
         if(str[t]=='0')
         {
           l[cnt++]=t;
         }    
        }
        l[cnt++]=n;
        if(m>=cnt-2)
        {
            printf("%d\n",n);
            continue;
        }
        for(int t=1;t<cnt-m;t++)
        {
            ans=max(ans,l[t+m]-l[t-1]-1);
        }
        cout<<ans<<endl; 
        
    }
    return 0;
}

 

上一篇:Python进阶之路 多重赋值技巧


下一篇:P1801 黑匣子_NOI导刊2010提高(06) 堆