zoukankan      html  css  js  c++  java
  • 字典树+博弈 CF 455B A Lot of Games(接龙游戏)

    题目链接

    题意:

      A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏。问A先手,经过k轮游戏,最后胜利的人是谁。

    思路:

      很显然先将n个字符串插入到字典树上,因为字典树上有分叉,不能仅仅判断字符串长度奇偶性来判断。字典树看成无环的状态图,如果按照拓扑排序逆序进行排序,在判断每个节点的时候,它的后继都已经判断过了。定义两个数组can_win[u], can_lose[u],表示u节点走下去“可能赢吗?”以及u节点走下去”可能输吗?“,那么取反就是必胜和必败态了,“可能赢”<-对手下一步不可能赢,”可能输“<-对手下一步不可能输。

    代码:

    #include <bits/stdc++.h>
    
    const int N = 1e5 + 5;
    char str[N];
    int ch[N][26];
    int sz;
    
    bool can_win[N], can_lose[N];
    
    void init() {
        memset (ch[0], 0, sizeof (ch[0]));
        sz = 1;
    }
    
    void insert(char *s) {
        int u = 0, c;
        for (int i=0; s[i]; ++i) {
            c = s[i] - 'a';
            if (!ch[u][c]) {
                memset (ch[sz], 0, sizeof (ch[sz]));
                ch[u][c] = sz++;
            }
            u = ch[u][c];
        }
    }
    
    void DFS(int u) {
        can_win[u] = can_lose[u] = false;
        bool is_leaf = true;
        for (int c=0; c<26; ++c) {
            int v = ch[u][c];
            if (v) {
                is_leaf = false;
                DFS (v);
                can_win[u] |= !can_win[v];
                can_lose[u] |= !can_lose[v];
            }
        }
        if (is_leaf) {
            can_lose[u] = true;
        }
    }
    
    int main() {
        int n, k;
        scanf ("%d%d", &n, &k);
        init ();
        for (int i=0; i<n; ++i) {
            scanf ("%s", str);
            insert (str);
        }
        
        DFS (0);
    
        if (!can_win[0]) {
            puts ("Second");  //of course!
        } else if (can_lose[0]) {
            puts ("First");  //can lose && can win, control!
        } else {
            //can win && !can lose, change A and B every turn!
            printf ("%s
    ", (k & 1) ? "First" : "Second");
        }
        return 0;    
    }
    

      

  • 相关阅读:
    列表标签
    超链接标签
    HTML:如何把一个无序列表转换成横向菜单
    window界面控制
    C++文件读写
    宽度,对齐方式的设置
    取出一个整数的每一位
    求两个数的最大公约数
    判断素数
    天才ACM ---待复习标志
  • 原文地址:https://www.cnblogs.com/Running-Time/p/5674693.html
Copyright © 2011-2022 走看看