• CF1244F Chips 的题解


    题目的字面意思:

    就是说给出了一个环,然后对于每一个位置i判断他的左右邻居中白色多还是黑色多,哪个多,这个i就变成什么颜色。一次循环称为一次操作,然后问在k次操作之后,这个环是什么样子。

    然后环的个数是2e5,k的个数是1e9

    看到数据之后,就可以明白,暴力一定是不行的。(废话一句)

    然后先给出两个定理:

    1、          

    对于BWWB这样的串,一定是不会再产生任何的变化了,那么我们就可以总结出,如果i位置的左右任意一个位置有一个和他相同,那么i就不会再变了。

    2、         

    如果位置i在第x次操作之后,不会再变化了(参考1),那么他左右的元素一定是在x+1轮不需要再变化了或者左右元素在这之前就已经不需要变化了。

    证明方式如下,对于任意一个还在变化的位置来说,左右元素一定和他不一样(类似与010或者101),那么位置i发生变化之后,一定会影响他左右的还在变化的位置,也就是说左右位置一定会在下一轮的操作变成不需要变化的。证明结束。

    详细的可以看代码,给了注释。

     

     1 #include <stdio.h>
     2 #include <queue>
     3 using namespace std;
     4 char s[200009];
     5 //预处理,就是可以快速的访问左右邻居,没啥好说 
     6 #define li (i-1+len)%len
     7 #define ri (i+1)%len
     8 #define lnow (now-1+len)%len
     9 #define rnow (now+1)%len
    10 //vis 数组 用来表示在 i 位置的元素什么时候开始不变化了 
    11 int vis[200009];
    12 int main()
    13 {
    14     queue <int> q;
    15     int len, k, now;
    16     scanf("%d %d %s", &len, &k, s);
    17     for(int i = 0; i < len; i++)
    18     {
    19         vis[i] = -1; // 初始化 i 为 -1 表示 一直在变化 
    20         if(s[li]==s[i]||s[i]==s[ri])  // 说明 i 位置从一开始是就是不需要变化的 
    21         {
    22             vis[i] = 0; 
    23             q.push(i);
    24         }
    25     }
    26     while(!q.empty())
    27     {
    28         now = q.front(); q.pop(); 
    29         if(vis[lnow]==-1)  // 只有当前的左右邻居还没有被处理掉的时候才需要 
    30         {
    31             vis[lnow] = vis[now] + 1; 
    32             q.push(lnow);
    33         }
    34         if(vis[rnow]==-1) 
    35         {
    36             vis[rnow] = vis[now] + 1; 
    37             q.push(rnow);
    38         }
    39     }
    40     for(int i = 0; i < len; i++)
    41     if(vis[i]==-1)  // 如果一直在变化 那么就是根据变化次数进行一个判断 
    42     {
    43         if(k&1) printf("%c", 'W'+'B'-s[i]);  //这个写法就很巧妙,多看dalao题解还是有好处啊 
    44         else printf("%c", s[i]);
    45     }else{
    46         //这里需要对vis (不需要进行变化的论数) 和 k(操作次数)的大小进行一个判断 
    47         if(min(vis[i], k)&1) printf("%c", 'W'+'B'-s[i]); 
    48         else printf("%c", s[i]);
    49     }
    50 }
  • 相关阅读:
    好元素(good)
    三条线 (Standard IO)
    计数排序-自然顺序Comparable
    贪心算法之田忌赛马
    bzoj3400
    bzoj1704
    CF Round #456 (Div. 2)
    LA3029
    bzoj3000
    bzoj3623
  • 原文地址:https://www.cnblogs.com/loenvom/p/11872665.html
Copyright © 2020-2023  润新知