two_pointers

Posted sjsjsj-minus-si

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了two_pointers相关的知识,希望对你有一定的参考价值。

CF660C

/*
reference:
    
translation:
    n个长度的01串,可以改变k个0到1,求最长连续1的长度
    n<=3e5+10,1<=k<=n<=3e5+10
    ->即是求最长只包含k个0的01串长度 
solution:
    1.O(n^3)枚举左右端点,判断其间0的个数是否<=k;
    2.O(n^2)[l,r]和[l,r+1]的联系很紧密,只需判断a[r+1]就可O(1)转移
    3.O(n)取尺法(two_pointer),O(n)遍历,右端点0的个数>k 时移动左端点到0的个数<=k 
trigger:
    
note:
    *
record:

date:
    2019.09.05
*/
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define dwn(i,a,b) for(int i=a;i>=b;--i) 
template <typename T> inline void rd(T &x)x=0;char c=getchar();int f=0;while(!isdigit(c))f|=c=='-';c=getchar();while(isdigit(c))x=(x<<1)+(x<<3)+(c^48);c=getchar();x=f?-x:x; 
inline void write(int n)if(n==0)return;write(n/10);putchar(n%10+'0');
#define mem(a,b) memset(a,b,sizeof(a))
#define ee(i,u) for(int i=head[u];i;i=e[i].next)

const int N = 3e5+10;

int n,k,cnt,ans;
int a[N];
bool vis[N];

#undef int
int main()
#define int long long
    #ifdef WIN32
    freopen("","r",stdin);
    #endif
    rd(n),rd(k);
    rep(i,1,n)rd(a[i]);
    for(int i=1,j=1;i<=n;++i)
        if(a[i]==0)
            cnt++;
            vis[i]=1;
        
        while(cnt>k && j<i)
            if(a[j]==0)cnt--;
            vis[j]=0;
            j++;
        
        ans=max(i-j+1,ans);
    
    printf("%lld\n",ans);
    rep(i,1,n)printf("%lld ",vis[i]?1:a[i]);
    return 0;

/*
7 1 
1 0 0 1 1 0 1
*/
/*
4 
1 0 0 1 1 1 1
*/
/*
10 2 
1 0 0 1 0 1 0 1 0 1
*/
/*
5 
1 0 0 1 1 1 1 1 0 1
*/
//多组解任意输出一种 

以上是关于two_pointers的主要内容,如果未能解决你的问题,请参考以下文章