zoukankan      html  css  js  c++  java
  • Codeforces Round #184 (Div. 2) E. Playing with String(博弈)

    题目大意

    两个人轮流在一个字符串上删掉一个字符,没有字符可删的人输掉游戏

    删字符的规则如下:

      1. 每次从一个字符串中选取一个字符,它是一个长度至少为 3 的奇回文串的中心

      2. 删掉该字符,同时,他选择的那个字符串分成了两个独立的字符串

    现在问,先手是否必胜,如果先手必胜,输出第一步应该删掉第几个字符,有多解的话,输出序号最小的那个

    字符串的长度不超过5000,只包含小写英文字母

    做法分析

    可以这样考虑:将所有的长度大于等于 3(其实只需要找长度为 3 的就行)的奇回文串的中心标记出来

    我们将连续的中心视为一个片段,那么,显然,游戏是进行在片段上面的,所以,游戏被分解成了多个子游戏的和

    对于每一个片段(子游戏),我们考虑它的 sg 函数,显然,sg 函数只和这个片段的长度有关,于是定义状态 sg[len] 表示长度为 len 的片段的 sg 值。怎么得到当前状态的下一子状态呢?

      如果删掉的是片段的两端,子状态分成了一个长度为 0 和长度为 len-2 的子片段

      如果删掉的是片段的中间,子状态分成了一个长度为 i 和长度为 len-3-i 的子片段

    这样,暴力出 sg 值,再依次的枚举第一次删掉的字符就可以解决这题了

    参考代码

     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 const int N=5006;
     8 
     9 char buff[N];
    10 int sg[N];
    11 
    12 int GET_SG(int len) {
    13     if(sg[len]!=-1) return sg[len];
    14     bool vs[N];
    15     memset(vs, 0, sizeof vs);
    16     vs[GET_SG(len-2)]=1;
    17     for(int i=1; i+i<len; i++) vs[GET_SG(i-1)^(GET_SG(len-2-i))]=1;
    18     for(int i=0; i<N; i++) if(!vs[i]) return sg[len]=i;
    19 }
    20 
    21 int hehe(int L, int R) {
    22     int sum=0;
    23     for(int i=L+1; i<R; i++) if(buff[i-1]==buff[i+1]) {
    24         int id=i;
    25         while(i<R && buff[i+1]==buff[i-1]) i++;
    26         sum^=sg[i-id];
    27     }
    28     return sum;
    29 }
    30 
    31 int main() {
    32     memset(sg, -1, sizeof sg);
    33     sg[0]=0, sg[1]=1;
    34     for(int i=2; i<N; i++) if(sg[i]==-1) GET_SG(i);
    35     while(scanf("%s", buff)!=EOF) {
    36         bool flag=1;
    37         for(int i=1, len=(int)strlen(buff); i<len-1; i++) {
    38             if(buff[i-1]!=buff[i+1]) continue;
    39             if(hehe(0, i-1)^hehe(i+1, len-1)) continue;
    40             printf("First
    %d
    ", i+1);
    41             flag=0;
    42             break;
    43         }
    44         if(flag) printf("Second
    ");
    45     }
    46     return 0;
    47 }
    E. Playing with String

    题目链接 & AC 通道

    Codeforces Round #184 (Div. 2) E. Playing with String

  • 相关阅读:
    经济危机下,自主创业已成为一种时代潮流?
    曾靖雯(帮别人名字作诗)
    四大内伤造就80后创业高失败率
    如何让创业的路不再崎岖
    叶莉(帮别人名字作诗)
    谁能够在萧条中生存?历史总是惊人相似的(转)
    哪种书最适合创业者阅读
    中西部崛起 关键是要激发普遍的创业热情
    每日英语:Dating in China Is a Largely Commercial Transaction
    每日英语:Poor Chinese Schools Tell Students: Bring Your Own Desks
  • 原文地址:https://www.cnblogs.com/zhj5chengfeng/p/3254613.html
Copyright © 2011-2022 走看看