zoukankan      html  css  js  c++  java
  • CodeForces456D A Lot of Games

    题意:两个人进行k场比赛,开始有一个空串,每场比赛两个人轮流加字符使得字符串至少是原来n个串的1个串的前缀,每场比赛输的人下一次比赛先手

    题解:可以发现是前缀,可以想到用字典树判断其中一场的胜负。。。但是这里有坑,假如先手可胜可负k为偶数,那么他可以在倒数第二场故意输给你,这样最后一场就是先手决定

    这里我们考虑先手输的话无论多少场都是输, 先手必胜的话就要看奇偶,先手可胜可负先手可以故意输使得他获胜,那么我们对每一个节点可以有4种状态(必胜,必败,可胜可败,未知)

    所有子节点必胜那么父节点必败,所有子节点必败那么父节点必胜,子节点有胜有负那么就是父节点就是有胜有负

    #include <bits/stdc++.h>
    #define maxn 101000
    #define INF 0x3f3f3f3f
    typedef long long ll;
    using namespace std;
    struct Tire{
        int ch[maxn][30],sz;
        Tire(){sz = 1;memset(ch, 0, sizeof(ch));}
        int idx(char c){return c-'a';}
        void insert(char *s){
            int u = 0,n = strlen(s);
            for(int i=0;i<n;i++){
                int c = idx(s[i]);
                if(!ch[u][c]){
                    memset(ch[sz], 0, sizeof(ch[sz]));
                    ch[u][c] = sz++;
                }
                u = ch[u][c];
            }
        }
        void dfs(int x,int &a,int &b){
            int flag = 1, c, d;
            a = b = 0;//默认未知
            for(int i=0;i<26;i++){
                int u = ch[x][i];
                if(u){
                    flag = 0;
                    dfs(u, c, d);
                    if(c == 0) a = 1;
                    if(d == 0) b = 1;
                    //必胜与可胜可败
                }
            }
            if(flag) a = 0, b = 1;//叶子节点必败
        }
    }Tir;
    char s[maxn];
    int main(){
        int n, k, a=0, b=0;
        scanf("%d%d", &n, &k);
        for(int i=0;i<n;i++){
            scanf("%s", s);
            Tir.insert(s);
        }
        Tir.dfs(0, a, b);
        if(a&&b) printf("First
    ");
        else if(k&1&&a) printf("First
    ");
        else printf("Second
    ");
        return 0;
    }
  • 相关阅读:
    小球掉落
    String当中与转换相关常用的方法有
    字符串的截取方法
    golang 管道
    golang--协程之间通信的方式
    golang--goroutine
    go 时间操作
    吉格勒定理
    检视阅读
    git branch -a发现分支显示不全
  • 原文地址:https://www.cnblogs.com/Noevon/p/7828438.html
Copyright © 2011-2022 走看看