zoukankan      html  css  js  c++  java
  • 思维+双指针+环——cf1244F

    /*
    可以发现一个性质:连续两个相同色块永远不会变色
    继而可以发现,这个色段每次迭代都向左向右拓展长度1,直到撞上其他扩张的色段 
    所以预处理出所有连续色段,然后对于所有不在色段里的点,我们可以预测其最终的颜色:
        其本身每次迭代改变一次颜色,如果k>= 离其最近的那个色段到其的距离Len,那么其就会被那个色段覆盖
        那么就要预处理出这些点两侧最近的色段距离和颜色 
        
    由于是环形,所以扩张两倍即可来求边界 
    */
    #include<bits/stdc++.h>
    #include<vector>
    using namespace std;
    #define N 400005
     
    int f[N],c[N],k,n,L[N],R[N];
    char s[N];
     
    int main(){
        cin>>n>>k;
        memset(c,0x3f,sizeof c);
        scanf("%s",s+1);
        for(int i=1;i<=n;i++)
            if(s[i]=='B')c[i]=c[i+n]=0;
            else c[i]=c[i+n]=1;
        c[0]=c[n];c[2*n+1]=c[1];
        
        for(int i=1;i<=2*n;i++)
            if(c[i]==c[i-1] || c[i]==c[i+1])
                f[i]=1;//连续点标记为1 
        
        //特判没有连续段,都是连续段
        int cnt=0;
        for(int i=1;i<=n;i++)cnt+=f[i];
        if(cnt==0){//无连续段 
            if(k%2==0){
                printf("%s",s+1);
            }
            else {
                for(int i=1;i<=n;i++)
                    if(s[i]=='B')cout<<'W';
                    else cout<<'B';
                puts("");
            }
            return 0;
        }
        else if(cnt==n){
            printf("%s",s+1);
            return 0;
        } 
        
        //处理左边界 
        int p=0;
        while(f[p+1]!=1)++p;//找到第一个连续色段 
        for(int i=p+1;i<=2*n;i++)
            if(!f[i])L[i]=p;
            else  p=i;
        
        //处理右边界
        p=2*n+1;
        while(f[p-1]!=1)--p;
        for(int i=p-1;i>=1;i--)
            if(!f[i])R[i]=p;
            else p=i;
    //010011,010011        
        for(int i=1;i<=n;i++){//回到环形上 
                if(!f[i] && L[i]==0)
                    L[i]=L[i+n];
                if(!f[i] && R[i]>n)
                    R[i]-=n;
            }
        
        for(int i=1;i<=n;i++)
            if(f[i]){
                cout<<s[i];
            }
            else {
                int disl,disr;
                if(L[i]>i)
                    disl=n-L[i]+i;
                else 
                    disl=i-L[i];
                
                if(R[i]<i)
                    disr=R[i]+n-i;
                else    
                    disr=R[i]-i;
                    
                int dis=min(disl,disr);
                if(dis<=k){
                    if(disl<disr){//被左侧覆盖 
                        if(disl<i)
                            cout<<s[i-disl];
                        else cout<<s[i+n-disl]; 
                    }
                    else {//被右侧覆盖 
                        if(i+disr<=n)
                            cout<<s[i+disr];
                        else cout<<s[i+disr-n];
                    }
                }
                else {
                    int now=(c[i]+k)%2;
                    if(now==0)cout<<"B";
                    else cout<<"W";
                } 
            }
        puts("");
    }
  • 相关阅读:
    jqeuery $.ajax 与后台jsone交互
    SpringMVC3.2+JPA使用注解的方式环境搭建
    SpringMVC+JPA使用注入的方式环境搭建
    EasyUI_tree根据数据库数据生成树形结构JSON格式
    ACM竞赛高手比其他程序员水平高很多吗?
    hdu 1028 Ignatius and the Princess III(DP)
    9513 防空洞
    hdu 1398 Square Coins(简单dp)
    FZU 1608 Huge Mission(线段树)
    poj2528 Mayor's posters(线段树之成段更新)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/11724525.html
Copyright © 2011-2022 走看看